X-Git-Url: https://git.distorted.org.uk/~mdw/lisp/blobdiff_plain/b73ffb8235ffb6f3bce6ac42731e19d3be846067..2b525992937f759211ea42e6e6f2bf0e695de96c:/safely.lisp diff --git a/safely.lisp b/safely.lisp index 84a06c4..43ea4fe 100644 --- a/safely.lisp +++ b/safely.lisp @@ -110,10 +110,26 @@ (safely-trail safe)) stream)) +#+clisp +(progn + (ffi:def-call-out %rename (:name "rename") + (:language :stdc) + (:library "libc.so.6") + (:arguments (from ffi:c-string) + (to ffi:c-string)) + (:return-type ffi:int))) + (declaim (inline rename)) (defun rename (old new) - #-clisp (rename-file old new) - #+clisp (posix:copy-file old new :method :rename)) + #-clisp + (let ((target (make-pathname :directory '(:relative) + :defaults new))) + (rename-file old target)) + + #+clisp + (let ((rc (%rename (namestring old) (namestring new)))) + (when (= rc -1) + (error "Failed to rename ~S to ~S: ~A" old new (posix:strerror))))) (defun delete-file-without-moaning (file) "Delete the FILE, ignoring errors." @@ -179,9 +195,7 @@ :method :hardlink :if-exists nil))) - - - #-(or cmu sbcl) + #-(or cmu sbcl clisp) ;; Otherwise just copy the file contents and hope for the best. (with-open-file (input file :element-type :default) (multiple-value-bind @@ -220,23 +234,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 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)