diff options
| author | Xavier Leroy <xavierleroy@users.noreply.github.com> | 2017-08-30 18:16:27 +0200 |
|---|---|---|
| committer | Alain Frisch <alain@frisch.fr> | 2017-08-30 18:16:27 +0200 |
| commit | 3e0aadf7b02de0e680c6b8cabcb719fe753fbf85 (patch) | |
| tree | 4bf1381f31b2eb10933d1c3714a3afae5227bf05 /otherlibs | |
| parent | 782bac2aebfbff848dad4e75b9757151cc2c1476 (diff) | |
| download | ocaml-3e0aadf7b02de0e680c6b8cabcb719fe753fbf85.tar.gz | |
Reimplement Sys.rename under Win32 to be more POSIX (#1306)
* Reimplement Sys.rename under Win32 to be more POSIX
Specifically: "Sys.rename src dst" no longer fails if file "dst" exists,
but replaces it with file "src", as in POSIX.
Test added.
* Sys.rename: document the "replace if existing" behavior
Now that we have this behavior under Win32, let's guarantee it.
* byterun/win32.c: typos in names of error codes
* Tests for Unix.rename similar to those for Sys.rename
* win32unix/rename.c: simplify the implementation
All versions of Windows we support provide MoveFileEx.
* Sys.remove: for backward compatibility, copy if cannot move
This is what the old implementation (based on MoveFile() and on rename() from the CRT) did.
* Improve documentation of Sys.remove
* Improve documentation of Unix.rename
Bring it in line with that of Sys.rename.
Diffstat (limited to 'otherlibs')
| -rw-r--r-- | otherlibs/unix/unix.mli | 7 | ||||
| -rw-r--r-- | otherlibs/win32unix/rename.c | 20 |
2 files changed, 9 insertions, 18 deletions
diff --git a/otherlibs/unix/unix.mli b/otherlibs/unix/unix.mli index d134157061..32ea7f13a6 100644 --- a/otherlibs/unix/unix.mli +++ b/otherlibs/unix/unix.mli @@ -557,7 +557,12 @@ val unlink : string -> unit *) val rename : string -> string -> unit -(** [rename old new] changes the name of a file from [old] to [new]. *) +(** [rename old new] changes the name of a file from [old] to [new], + moving it between directories if needed. If [new] already + exists, its contents will be replaced with those of [old]. + Depending on the operating system, the metadata (permissions, + owner, etc) of [new] can either be preserved or be replaced by + those of [old]. *) val link : string -> string -> unit (** [link source dest] creates a hard link named [dest] to the file diff --git a/otherlibs/win32unix/rename.c b/otherlibs/win32unix/rename.c index 155a73fb94..dee4cd5eeb 100644 --- a/otherlibs/win32unix/rename.c +++ b/otherlibs/win32unix/rename.c @@ -19,25 +19,11 @@ CAMLprim value unix_rename(value path1, value path2) { - static int supports_MoveFileEx = -1; /* don't know yet */ - BOOL ok; - caml_unix_check_path(path1, "rename"); caml_unix_check_path(path2, "rename"); - if (supports_MoveFileEx < 0) { - OSVERSIONINFO VersionInfo; - VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - supports_MoveFileEx = - (GetVersionEx(&VersionInfo) != 0) - && (VersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); - } - if (supports_MoveFileEx > 0) - ok = MoveFileEx(String_val(path1), String_val(path2), - MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH | - MOVEFILE_COPY_ALLOWED); - else - ok = MoveFile(String_val(path1), String_val(path2)); - if (! ok) { + if (! MoveFileEx(String_val(path1), String_val(path2), + MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH | + MOVEFILE_COPY_ALLOWED)) { win32_maperr(GetLastError()); uerror("rename", path1); } |
