فهرست منبع

libobs/util: Add os_safe_replace function

Allows safely/atomically replacing a file and creating a backup of the
original.  The reason for adding this function is because Microsoft
provides a ReplaceFile function which does this in a single call.
jp9000 8 سال پیش
والد
کامیت
651d80c0df
3فایلهای تغییر یافته به همراه38 افزوده شده و 0 حذف شده
  1. 7 0
      libobs/util/platform-nix.c
  2. 29 0
      libobs/util/platform-windows.c
  3. 2 0
      libobs/util/platform.h

+ 7 - 0
libobs/util/platform-nix.c

@@ -432,6 +432,13 @@ int os_rename(const char *old_path, const char *new_path)
 	return rename(old_path, new_path);
 }
 
+int os_safe_replace(const char *target, const char *from, const char *backup)
+{
+	if (backup && rename(target, backup) != 0)
+		return -1;
+	return rename(from, target);
+}
+
 #if !defined(__APPLE__)
 os_performance_token_t *os_request_high_performance(const char *reason)
 {

+ 29 - 0
libobs/util/platform-windows.c

@@ -557,6 +557,35 @@ error:
 	return code;
 }
 
+int os_safe_replace(const char *target, const char *from, const char *backup)
+{
+	wchar_t *wtarget = NULL;
+	wchar_t *wfrom = NULL;
+	wchar_t *wbackup = NULL;
+	int code = -1;
+
+	if (!target || !from)
+		return -1;
+	if (!os_utf8_to_wcs_ptr(target, 0, &wtarget))
+		return -1;
+	if (!os_utf8_to_wcs_ptr(from, 0, &wfrom))
+		goto fail;
+	if (backup && !os_utf8_to_wcs_ptr(backup, 0, &wbackup))
+		goto fail;
+
+	if (ReplaceFileW(wtarget, wfrom, wbackup, 0, NULL, NULL)) {
+		code = 0;
+	} else if (GetLastError() == ERROR_FILE_NOT_FOUND) {
+		code = MoveFile(wfrom, wtarget) ? 0 : -1;
+	}
+
+fail:
+	bfree(wtarget);
+	bfree(wfrom);
+	bfree(wbackup);
+	return code;
+}
+
 BOOL WINAPI DllMain(HINSTANCE hinst_dll, DWORD reason, LPVOID reserved)
 {
 	switch (reason) {

+ 2 - 0
libobs/util/platform.h

@@ -161,6 +161,8 @@ EXPORT int os_mkdir(const char *path);
 EXPORT int os_mkdirs(const char *path);
 EXPORT int os_rename(const char *old_path, const char *new_path);
 EXPORT int os_copyfile(const char *file_in, const char *file_out);
+EXPORT int os_safe_replace(const char *target_path, const char *from_path,
+		const char *backup_path);
 
 EXPORT char *os_generate_formatted_filename(const char *extension, bool space,
 		const char *format);