move-file previously had inconsistent behavior on Windows and unixes.
This unifies the behavior to the common case (just get 'er done), while
also introducing an obviously named word, move-file-atomically, to
handle the case where you need an atomic file primitive.
Fixes #1772
HELP: move-file
{ $values { "from" "a pathname string" } { "to" "a pathname string" } }
-{ $description "Moves or renames a file." }
+{ $description "Moves or renames a file. This operation is not guaranteed to be atomic. In particular, if you attempt to move a file across volumes, this will copy the file and then delete the original in a nontransactional manner." }
+{ $errors "Throws an error if the file does not exist or if the move operation fails." }
+{ $see-also move-file-atomically } ;
+
+HELP: move-file-atomically
+{ $values { "from" "a pathname string" } { "to" "a pathname string" } }
+{ $description "Moves or renames a file as an atomic operation." }
{ $errors "Throws an error if the file does not exist or if the move operation fails." } ;
HELP: move-file-into
! Moving and renaming files
HOOK: move-file io-backend ( from to -- )
+HOOK: move-file-atomically io-backend ( from to -- )
: move-file-into ( from to -- )
to-directory move-file ;
touch-mode file-mode open-file close-file
] if ;
-M: unix move-file ( from to -- )
+M: unix move-file-atomically ( from to -- )
[ normalize-path ] bi@ [ rename ] unix-system-call drop ;
+M: unix move-file ( from to -- )
+ [ move-file-atomically ] [
+ dup errno>> EXDEV = [
+ drop [ copy-file ] [ drop delete-file ] 2bi
+ ] [ rethrow ] if
+ ] recover ;
+
M: unix delete-file ( path -- ) normalize-path unlink-file ;
M: unix make-directory ( path -- )
M: windows move-file ( from to -- )
[ normalize-path ] bi@ MoveFile win32-error=0/f ;
+M: windows move-file-atomically ( from to -- )
+ [ normalize-path ] bi@ 0 MoveFileEx win32-error=0/f ;
+
ERROR: file-delete-failed path error ;
: delete-file-throws ( path -- )
! FUNCTION: Module32NextW
! FUNCTION: MoveFileA
! FUNCTION: MoveFileExA
-! FUNCTION: MoveFileExW
+FUNCTION: BOOL MoveFileExW ( LPCSTR lpExistingFile, LPCSTR lpNewFileName, DWORD dwFlags )
+ALIAS: MoveFileEx MoveFileExW
FUNCTION: BOOL MoveFileW ( LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName )
ALIAS: MoveFile MoveFileW
! FUNCTION: MoveFileWithProgressA