X-Git-Url: https://git.distorted.org.uk/~mdw/lisp/blobdiff_plain/2d9f4fc0d90318686f2d2f691c893174ef1bbc0c..562ed2ddc451abe9be0ec5bb9684b2df56942d8f:/safely.lisp diff --git a/safely.lisp b/safely.lisp index 4830a99..9809f07 100644 --- a/safely.lisp +++ b/safely.lisp @@ -110,6 +110,13 @@ (safely-trail safe)) stream)) +(declaim (inline rename)) +(defun rename (old new) + (let ((target (make-pathname :directory '(:relative) + :defaults new))) + #-clisp (rename-file old target) + #+clisp (rename-file old target :if-exists :overwrite))) + (defun delete-file-without-moaning (file) "Delete the FILE, ignoring errors." (handler-case (delete-file file) @@ -118,7 +125,7 @@ (defun rename-file-without-moaning (old new) "Rename OLD to NEW, ignoring errors, and without doing any stupid name mangling." - (handler-case (rename-file old new) + (handler-case (rename old new) (file-error () nil))) (defun safely-unwind (trail) @@ -166,6 +173,16 @@ (and from to (unix-link from to))))) + #+clisp + (generate-fresh-file-name file tag + (lambda (name) + (posix:copy-file (namestring file) + (namestring name) + :method :hardlink + :if-exists nil))) + + + #-(or cmu sbcl) ;; Otherwise just copy the file contents and hope for the best. (with-open-file (input file :element-type :default) @@ -205,23 +222,23 @@ (loop (unless trail (return)) - (let ((job (pop trail))) - (ecase (car job) - (:shunt (destructuring-bind (tag new file) job - (declare (ignore tag)) - (push `(:rmtmp ,new) revert) - (if (probe-file file) - (let ((old (safe-copy file "old"))) - (push `(:rmtmp ,old) cleanup) - (push `(:revert ,old ,file) revert)) - (push `(:rmtmp ,file) revert)) - (rename-file new file))) - (:delete (destructuring-bind (tag file) job - (declare (ignore tag)) - (let ((old (safe-copy file "delete"))) - (push `(:revert ,old ,file) revert) - (push `(:rmtmp ,old) cleanup) - (delete-file file))))))) + (let ((job (pop trail))) + (ecase (car job) + (:shunt (destructuring-bind (tag new file) job + (declare (ignore tag)) + (push `(:rmtmp ,new) revert) + (if (probe-file file) + (let ((old (safe-copy file "old"))) + (push `(:rmtmp ,old) cleanup) + (push `(:revert ,old ,file) revert)) + (push `(:rmtmp ,file) revert)) + (rename new file))) + (:delete (destructuring-bind (tag file) job + (declare (ignore tag)) + (let ((old (safe-copy file "delete"))) + (push `(:revert ,old ,file) revert) + (push `(:rmtmp ,old) cleanup) + (delete-file file))))))) (setf revert nil)) (safely-unwind trail) (safely-unwind revert)