X-Git-Url: https://git.distorted.org.uk/~mdw/lisp/blobdiff_plain/b2c12b4eaf6e5c43791d95080a243c35f97ee488..2d9f4fc0d90318686f2d2f691c893174ef1bbc0c:/safely.lisp diff --git a/safely.lisp b/safely.lisp index 0a05f8b..4830a99 100644 --- a/safely.lisp +++ b/safely.lisp @@ -30,6 +30,17 @@ #:safely-writing)) (in-package #:safely) +#+(or cmu sbcl) +(eval-when (:compile-toplevel :execute) + (import #+cmu '(ext:unix-namestring unix:unix-link) + #+sbcl '(sb-ext:native-namestring))) +#+cmu +(progn + (declaim (inline unix-namestring)) + (defun native-namestring (pathname &key as-file) + (declare (ignore as-file)) + (unix-namestring pathname nil))) + (defstruct (safely (:predicate safelyp)) "Stores information about how to commit or undo safe writes." (streams nil) @@ -136,19 +147,26 @@ (safely-unwind (safely-trail safe)) (safely-reset safe)) +#+sbcl +(defun unix-link (from to) + (sb-unix::int-syscall ("link" sb-alien:c-string sb-alien:c-string) + from to)) + (defun safe-copy (file tag) "Make a copy of the FILE. Return the new name." - #+cmu + #+(or cmu sbcl) ;; Use link(2) where available. (generate-fresh-file-name file tag (lambda (name) - (let ((from (ext:unix-namestring file t)) - (to (ext:unix-namestring name nil))) + (let ((from (native-namestring file + :as-file t)) + (to (native-namestring name + :as-file t))) (and from to - (unix:unix-link from to))))) + (unix-link from to))))) - #-cmu + #-(or cmu sbcl) ;; Otherwise just copy the file contents and hope for the best. (with-open-file (input file :element-type :default) (multiple-value-bind @@ -227,8 +245,7 @@ temporary file, and if BODY completes, it is renamed to FILE." (with-gensyms safe `(safely (,safe) - (let ((,stream (apply #'safely-open-output-stream - ,safe ,file ,open-args))) + (let ((,stream (safely-open-output-stream ,safe ,file ,@open-args))) ,@body)))) ;;;----- That's all, folks --------------------------------------------------