1.0.30.22: better DELETE-FILE on streams
authorNikodemus Siivola <nikodemus@random-state.net>
Fri, 31 Jul 2009 09:11:15 +0000 (09:11 +0000)
committerNikodemus Siivola <nikodemus@random-state.net>
Fri, 31 Jul 2009 09:11:15 +0000 (09:11 +0000)
 * Don't close the stream on Unix, so users can enjoy the normal
   Unixy-IO to unlinked files.

 * On Windows, close the stream with :ABORT NIL, so that there
   is no danger of close trying to delete file as well.

   Bug with DELETE-FILE trying to delete files twice reported by
   John Fremlin.

NEWS
src/code/filesys.lisp
tests/stream.impure.lisp
version.lisp-expr

diff --git a/NEWS b/NEWS
index 3071cb2..27fe085 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -27,6 +27,9 @@ changes relative to sbcl-1.0.30:
        documented.
     ** DECLARATION-INFORMATION now supports declaration name DECLARATION as
        well.
+  * bug fix: DELETE-FILE on streams no longer closes the stream with :ABORT T,
+    leading to possible attempts to delete the same file twice. See docstring
+    on DELETE-FILE for details. (reported by John Fremlin)
   * bug fix: the low-level debugger had 32-bit assumptions and was missing
     information about some array types. (thanks to Luis Oliveira)
   * bug fix: moderately complex combinations of inline expansions could
index 482b34b..0cac4e7 100644 (file)
@@ -471,17 +471,17 @@ or if PATHSPEC is a wild pathname."
 
 (defun delete-file (file)
   #!+sb-doc
-  "Delete the specified FILE."
-  (let* ((truename (probe-file file))
-         (namestring (when truename
-                       (native-namestring truename :as-file t))))
+  "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 OS 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 :abort t))
-    (unless namestring
-      (error 'simple-file-error
-             :pathname file
-             :format-control "~S doesn't exist."
-             :format-arguments (list file)))
+      (close file))
     (multiple-value-bind (res err) (sb!unix:unix-unlink namestring)
       (unless res
         (simple-file-perror "couldn't delete ~A" namestring err))))
index 3540257..863f4e9 100644 (file)
     (assert (let ((buffer (make-array 10 :element-type '(unsigned-byte 8))))
               (read-sequence buffer s))))
   (delete-file pathname))
+
+(with-test (:name :delete-file-on-streams)
+  (with-open-file (f "delete-file-on-stream-test.tmp"
+                     :direction :io)
+    (delete-file f)
+    #-win32
+    (progn
+      (write-line "still open" f)
+      (file-position f :start)
+      (assert (equal "still open" (read-line f)))))
+  (assert (not (probe-file "delete-file-on-stream-test.tmp"))))
 \f
 ;;; success
index 2f65b6c..7863d93 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.30.21"
+"1.0.30.22"