summaryrefslogtreecommitdiff
path: root/legacy/ecore/src/lib/ecore_file/ecore_file.c
diff options
context:
space:
mode:
authorNicholas Hughart <mekius@mekius.net>2008-09-02 02:44:47 +0000
committerNicholas Hughart <mekius@mekius.net>2008-09-02 02:44:47 +0000
commit4851309c8b0b83e657a1b63a6bc2ac630ebffc2c (patch)
tree4500bfeac807323e9444c155d620ed0682a12fdd /legacy/ecore/src/lib/ecore_file/ecore_file.c
parentf8cee23def6aa65d0c7299021091a19cbc58f9e6 (diff)
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.
SVN revision: 35787
Diffstat (limited to '')
-rw-r--r--legacy/ecore/src/lib/ecore_file/ecore_file.c52
1 files changed, 47 insertions, 5 deletions
diff --git a/legacy/ecore/src/lib/ecore_file/ecore_file.c b/legacy/ecore/src/lib/ecore_file/ecore_file.c
index 1e828385a0..ecb7b515f0 100644
--- a/legacy/ecore/src/lib/ecore_file/ecore_file.c
+++ b/legacy/ecore/src/lib/ecore_file/ecore_file.c
@@ -295,24 +295,66 @@ ecore_file_cp(const char *src, const char *dst)
295EAPI int 295EAPI int
296ecore_file_mv(const char *src, const char *dst) 296ecore_file_mv(const char *src, const char *dst)
297{ 297{
298 char buf[PATH_MAX];
299 int fd;
300
298 if (rename(src, dst)) 301 if (rename(src, dst))
299 { 302 {
303 // File cannot be moved directly because
304 // it resides on a different mount point.
300 if (errno == EXDEV) 305 if (errno == EXDEV)
301 { 306 {
302 struct stat st; 307 struct stat st;
303 308
309 // Make sure this is a regular file before
310 // we do anything fancy.
304 stat(src, &st); 311 stat(src, &st);
305 if (S_ISREG(st.st_mode)) 312 if (S_ISREG(st.st_mode))
306 { 313 {
307 ecore_file_cp(src, dst); 314 // Since we can't directly rename, try to
308 chmod(dst, st.st_mode); 315 // copy to temp file in the dst directory
309 ecore_file_unlink(src); 316 // and then rename.
310 return 1; 317 snprintf(buf, sizeof(buf), "%s/.%s.tmp.XXXXXX",
318 ecore_file_dir_get(dst),
319 ecore_file_file_get(dst));
320 fd = mkstemp(buf);
321 if(fd < 0)
322 {
323 perror("mkstemp");
324 goto FAIL;
325 }
326 close(fd);
327
328 // Copy to temp file
329 if(!ecore_file_cp(src,buf))
330 goto FAIL;
331
332 // Set file permissions of temp file to match src
333 chmod(buf, st.st_mode);
334
335 // Try to atomically move temp file to dst
336 if (rename(buf, dst))
337 {
338 // If we still cannot atomically move
339 // do a normal copy and hope for the best.
340 if(!ecore_file_cp(buf, dst))
341 goto FAIL;
342 }
343
344 // Delete temporary file and src
345 ecore_file_unlink(buf);
346 ecore_file_unlink(src);
347 goto PASS;
311 } 348 }
312 } 349 }
313 return 0; 350 goto FAIL;
314 } 351 }
352
353 PASS:
315 return 1; 354 return 1;
355
356 FAIL:
357 return 0;
316} 358}
317 359
318/** 360/**