mdw-base.lisp: Export symbols near their definitions.
[lisp] / safely.lisp
index 84a06c4..43ea4fe 100644 (file)
          (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."
                                               :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
          (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)