Another update to ecore_file_mv to make it work even better. Now even writes to...
authormekius <mekius@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 2 Sep 2008 02:44:47 +0000 (02:44 +0000)
committermekius <mekius@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 2 Sep 2008 02:44:47 +0000 (02:44 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/ecore@35787 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/ecore_file/ecore_file.c

index 1e82838..ecb7b51 100644 (file)
@@ -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;
 }
 
 /**