From: mekius Date: Tue, 2 Sep 2008 02:44:47 +0000 (+0000) Subject: Another update to ecore_file_mv to make it work even better. Now even writes to... X-Git-Tag: 2.0_alpha~194^2~1802 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2d77a1e30054adad32c441af6cd4ad478e6d367c;p=framework%2Fuifw%2Fecore.git Another update to ecore_file_mv to make it work even better. Now even writes to external devices will be atomic if possible. If it's still not possible, the old fallback method of just copying will be done. git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/ecore@35787 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- diff --git a/src/lib/ecore_file/ecore_file.c b/src/lib/ecore_file/ecore_file.c index 1e82838..ecb7b51 100644 --- a/src/lib/ecore_file/ecore_file.c +++ b/src/lib/ecore_file/ecore_file.c @@ -295,24 +295,66 @@ ecore_file_cp(const char *src, const char *dst) EAPI int ecore_file_mv(const char *src, const char *dst) { + char buf[PATH_MAX]; + int fd; + if (rename(src, dst)) { + // File cannot be moved directly because + // it resides on a different mount point. if (errno == EXDEV) { struct stat st; + // Make sure this is a regular file before + // we do anything fancy. stat(src, &st); if (S_ISREG(st.st_mode)) { - ecore_file_cp(src, dst); - chmod(dst, st.st_mode); - ecore_file_unlink(src); - return 1; + // Since we can't directly rename, try to + // copy to temp file in the dst directory + // and then rename. + snprintf(buf, sizeof(buf), "%s/.%s.tmp.XXXXXX", + ecore_file_dir_get(dst), + ecore_file_file_get(dst)); + fd = mkstemp(buf); + if(fd < 0) + { + perror("mkstemp"); + goto FAIL; + } + close(fd); + + // Copy to temp file + if(!ecore_file_cp(src,buf)) + goto FAIL; + + // Set file permissions of temp file to match src + chmod(buf, st.st_mode); + + // Try to atomically move temp file to dst + if (rename(buf, dst)) + { + // If we still cannot atomically move + // do a normal copy and hope for the best. + if(!ecore_file_cp(buf, dst)) + goto FAIL; + } + + // Delete temporary file and src + ecore_file_unlink(buf); + ecore_file_unlink(src); + goto PASS; } } - return 0; + goto FAIL; } + + PASS: return 1; + + FAIL: + return 0; } /**