delete-file on stream deletes the file twice and raises error

Bug #406271 reported by John Fremlin
14
This bug affects 2 people
Affects Status Importance Assigned to Milestone
SBCL
Fix Released
Medium
Unassigned

Bug Description

(let ((stream (open "bug" :direction :output :if-does-not-exist :create)))
  (assert stream)
  (delete-file stream))

causes error couldn't delete bug: No such file or directory
   [Condition of type SB-INT:SIMPLE-FILE-ERROR]

delete-file calls (close :abort t) first, which deletes the file, then tries to delete the file a second time, causing the error.

This is very annoying because it is useful to be able to detect if the file was safely deleted. It means anardb does not work on SBCL.

This is SBCL 1.0.29.11.debian,

Changed in sbcl:
status: New → Confirmed
importance: Undecided → Medium
Revision history for this message
Stas Boukarev (stassats) wrote :

Here's my take on it.

Revision history for this message
Stas Boukarev (stassats) wrote :

Here is a better variant---doesn't call probe-file twice on non-streams.

Revision history for this message
John Fremlin (jf-msi) wrote :

Suppose the close :abort t deleted the file, then another process created a new file with the same name. You would delete the new file too, for a total of two deletions.

How about first deleting the file, then closing without :abort t?

Revision history for this message
James Y Knight (foom) wrote :

You can't delete open files in Windows.

Revision history for this message
Nikodemus Siivola (nikodemus) wrote :

I would be inclined to go with something like this:

(defun delete-file (file)
  #!+sb-doc
  "Delete the specified FILE.

If FILE is a stream, on Windows the stream is closed immediately. On Unix
plaforms the stream remains open, allowing IO to continue: the resources
associated with the deleted file remain available till the stream is closed as
per standard Unix unlink() behaviour."
  (let* ((truename (truename file))
         (namestring (native-namestring truename :as-file t)))
    #!+win32
    (when (streamp file)
      (close file))
    (multiple-value-bind (res err) (sb!unix:unix-unlink namestring)
      (unless res
        (simple-file-perror "couldn't delete ~A" namestring err))))
  t)

Revision history for this message
John Fremlin (jf-msi) wrote :

That looks perfect, thanks for your time!

Changed in sbcl:
status: Confirmed → Fix Committed
Changed in sbcl:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.