lavf: Use MoveFileEx instead of rename/_wrename on windows
authorMartin Storsjö <martin@martin.st>
Tue, 25 Nov 2014 09:08:59 +0000 (11:08 +0200)
committerMartin Storsjö <martin@martin.st>
Thu, 27 Nov 2014 07:29:29 +0000 (09:29 +0200)
This allows getting the normal unix semantics, where a rename
allows replacing an existing file.

Based on a suggestion by Reimar Döffinger.

Signed-off-by: Martin Storsjö <martin@martin.st>
configure
libavformat/os_support.h

index 7b3faae..355a95b 100755 (executable)
--- a/configure
+++ b/configure
@@ -1466,6 +1466,7 @@ SYSTEM_FUNCS="
     localtime_r
     mach_absolute_time
     MapViewOfFile
+    MoveFileExA
     memalign
     mkstemp
     mmap
@@ -4096,6 +4097,7 @@ check_func_headers windows.h GetProcessAffinityMask
 check_func_headers windows.h GetProcessTimes
 check_func_headers windows.h GetSystemTimeAsFileTime
 check_func_headers windows.h MapViewOfFile
+check_func_headers windows.h MoveFileExA
 check_func_headers windows.h SetConsoleTextAttribute
 check_func_headers windows.h Sleep
 check_func_headers windows.h VirtualAlloc
index 4aa98bd..4949065 100644 (file)
@@ -170,14 +170,31 @@ static inline int win32_rename(const char *src_utf8, const char *dest_utf8)
         goto fallback;
     }
 
-    ret = _wrename(src_w, dest_w);
+    ret = MoveFileExW(src_w, dest_w, MOVEFILE_REPLACE_EXISTING);
     av_free(src_w);
     av_free(dest_w);
+    // Lacking proper mapping from GetLastError() error codes to errno codes
+    if (ret)
+        errno = EPERM;
     return ret;
 
 fallback:
     /* filename may be be in CP_ACP */
-    return rename(src_utf8, dest_utf8);
+#if HAVE_MOVEFILEEXA
+    ret = MoveFileExA(src_utf8, dest_utf8, MOVEFILE_REPLACE_EXISTING);
+    if (ret)
+        errno = EPERM;
+#else
+    /* Windows Phone doesn't have MoveFileExA. However, it's unlikely
+     * that anybody would input filenames in CP_ACP there, so this
+     * fallback is kept mostly for completeness. Alternatively we could
+     * do MultiByteToWideChar(CP_ACP) and use MoveFileExW, but doing
+     * explicit conversions with CP_ACP is allegedly forbidden in windows
+     * store apps (or windows phone), and the notion of a native code page
+     * doesn't make much sense there. */
+    ret = rename(src_utf8, dest_utf8);
+#endif
+    return ret;
 }
 
 #define mkdir(a, b) win32_mkdir(a)