[Filesystem] Fix for moving files on different file systems 49/144649/3
authorTomasz Marciniak <t.marciniak@samsung.com>
Wed, 16 Aug 2017 12:39:52 +0000 (14:39 +0200)
committerTomasz Marciniak <t.marciniak@samsung.com>
Thu, 17 Aug 2017 11:27:03 +0000 (13:27 +0200)
[Verification] Code compiles. Now files can be moved
between different mounted file systems.
TCT pass rate 100% (286/286/0/0/0)

Change-Id: I5b70bc96f14a53bcebd2b2db3f12748949aab410
Signed-off-by: Tomasz Marciniak <t.marciniak@samsung.com>
src/filesystem/filesystem_manager.cc

index 43f7462daaf22fe8d43d83d513d31c798f1ee379..15dd88cef2c2caaf8dd9e6ac40a168d0898647a1 100644 (file)
@@ -316,19 +316,53 @@ void FilesystemManager::Rename(
     const std::function<void(FilesystemError)>& error_cb) {
 
   LoggerD("enter");
+
   int status = rename(oldPath.c_str(), newPath.c_str());
-  if (0 == status) {
-    FilesystemStat fileStat = FilesystemStat::getStat(newPath);
-    if (fileStat.valid) {
-      success_cb(FilesystemStat::getStat(newPath));
-    } else {
-      LoggerE("Cannot perform stat on new path!");
+  if (0 != status) {
+    if(EXDEV != errno) {
+      LoggerE("Error while moving file");
       error_cb(FilesystemError::Other);
+      return;
+    }
+
+    LoggerD("Files are not on the same mounted file system");
+    //In case of EXDEV we need to copy and remove file
+    //EXDEV - oldpath and newpath are not on the same mounted file system.
+    //Linux permits a file system to be mounted at multiple points, but rename() does not work
+    //across different mount points, even if the same file system is mounted on both.
+
+    if (FilesystemError::None != copyFile(oldPath, newPath)) {
+      LoggerE("Error while copying file");
+      error_cb(FilesystemError::Other);
+      return;
+    }
+
+    struct stat fileStat;
+    if (0 != stat(oldPath.c_str(), &fileStat)) {
+      LoggerE("Error while getting file status [%s]", GetErrorString(errno).c_str());
+      error_cb(FilesystemError::Other);
+      return;
+    }
+
+    int ret = 0;
+    ret |= chmod(newPath.c_str(), fileStat.st_mode);
+    ret |= chown(newPath.c_str(), fileStat.st_uid, fileStat.st_gid);
+    if (0 != ret) {
+      LoggerE("Error while changing ownership/permissions [%s]", GetErrorString(errno).c_str());
+      remove(newPath.c_str());
+      error_cb(FilesystemError::Other);
+      return;
+    }
+
+    if (0 != remove(oldPath.c_str())) {
+      LoggerE("Error while removing file [%s]", GetErrorString(errno).c_str());
+      remove(newPath.c_str());
+      error_cb(FilesystemError::Other);
+      return;
     }
-  } else {
-    LoggerE("Cannot rename file: %s", GetErrorString(errno).c_str());
-    error_cb(FilesystemError::Other);
   }
+
+  success_cb(FilesystemStat::getStat(newPath));
 }
 
 void FilesystemManager::ReadDir(