From: Bruno H. <br...@cl...> - 2004-11-22 18:41:32
|
Pascal J.Bourguignon wrote: > > On posix, the rename(2) syscall has am important atomic semantic: > > > > If newpath already exists it will be atomically replaced (subject > > to a few conditions - see ERRORS below), so that there is no > > point at which another process attempting to access newpath will > > find it missing. > > > > If newpath exists but the operation fails for some reason rename > > guarantees to leave an instance of newpath in place. > > > > > > cmucl, sbcl, gcl, ecls all understand this semantic and implement > > RENAME-FILE using this posix syscall. > > > > Unfortunately, clisp doesn't. When there already exists a file under > > the target name, it returns an error instead of applying the standard > > posix semantics. This is on purpose. CLISP's behaviour is designed to be OS independent. Its notion of "file" is not the same as an inode on POSIX systems (as you can see from the PROBE-FILE / PROBE-DIRECTORY distinction). CLISP's behaviour of a pathname/file related function is chosen to be understandable and without surprises across platforms. Especially, without surprises that cause data loss. The POSIX rename(2) call is surprising because 1) it erases the target file by default, 2) it cannot move files across filesystems. Ad 1): I have no objections against adding a REPLACE-FILE function that uses rename(2) directly. Ad 2): CLISP also gives an error when it cannot move a file from one filesystem to another. This is a bug, which I will fix. (The GNU 'mv' program has it fixed for ca. ten years.) If you want a function that prefers to give an error in the case 2, like POSIX rename() does, add a keyword argument :ATOMICALLY to REPLACE-FILE. (REPLACE-FILE old-name new-name :ATOMICALLY T) Sam wrote: > those who want RENAME-FILE="mv -f" (as all other lisps do), now need > > (let ((real-dest (merge-pathnames dest source))) > (when (probe-file real-dest) (delete-file real-dest)) > (rename-file source real-dest)) This is good. It's explicit and portable. Bruno |