(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
+ (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."
(handler-case (delete-file file)
(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)
(and from to
(unix-link from to)))))
- #-(or cmu sbcl)
+ #+clisp
+ (generate-fresh-file-name file tag
+ (lambda (name)
+ (posix:copy-file (namestring file)
+ (namestring name)
+ :method :hardlink
+ :if-exists nil)))
+
+ #-(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
(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)