Add an implementation of copyTo() in the filesystem.cpp 78/76578/5
authorSungbae Yoo <sungbae.yoo@samsung.com>
Fri, 24 Jun 2016 08:56:21 +0000 (17:56 +0900)
committerSungbae Yoo <sungbae.yoo@samsung.com>
Mon, 27 Jun 2016 10:18:36 +0000 (19:18 +0900)
Signed-off-by: Sungbae Yoo <sungbae.yoo@samsung.com>
Change-Id: Id830a7e576916734a44328c865dc462b07b101b4

common/filesystem.cpp
common/filesystem.h
common/smack.cpp
server/zone/zone.cpp

index ffa455b..2a3b575 100755 (executable)
@@ -14,6 +14,7 @@
  *  limitations under the License
  */
 
+#include <sys/sendfile.h>
 #include <sys/types.h>
 #include <sys/mount.h>
 #include <sys/stat.h>
@@ -29,6 +30,7 @@
 #include <iostream>
 
 #include "filesystem.h"
+#include "smack.h"
 #include "error.h"
 #include "exception.h"
 
@@ -228,6 +230,46 @@ bool File::isHidden() const
     return false;
 }
 
+mode_t File::getMode() const
+{
+    struct stat st;
+    if (::stat(path.getPathname().c_str(), &st) != 0) {
+        throw runtime::Exception(runtime::GetSystemErrorMessage());
+    }
+
+    return st.st_mode;
+}
+
+uid_t File::getUid() const
+{
+    struct stat st;
+    if (::stat(path.getPathname().c_str(), &st) != 0) {
+        throw runtime::Exception(runtime::GetSystemErrorMessage());
+    }
+
+    return st.st_uid;
+}
+
+gid_t File::getGid() const
+{
+    struct stat st;
+    if (::stat(path.getPathname().c_str(), &st) != 0) {
+        throw runtime::Exception(runtime::GetSystemErrorMessage());
+    }
+
+    return st.st_gid;
+}
+
+size_t File::size() const
+{
+    struct stat st;
+    if (::stat(path.getPathname().c_str(), &st) != 0) {
+        throw runtime::Exception(runtime::GetSystemErrorMessage());
+    }
+
+    return st.st_size;
+}
+
 std::string File::toString() const
 {
     struct stat st;
@@ -266,6 +308,22 @@ void File::open(int flags)
     }
 }
 
+void File::open(int flags, mode_t mode)
+{
+    close();
+
+    while (1) {
+        descriptor = ::open(path.getPathname().c_str(), flags, mode);
+        if (descriptor == -1) {
+            if (errno != EINTR) {
+                continue;
+            }
+            throw runtime::Exception(runtime::GetSystemErrorMessage());
+        }
+        return;
+    }
+}
+
 void File::close()
 {
     if (descriptor == -1) {
@@ -278,8 +336,10 @@ void File::close()
                 continue;
             }
         }
-        return;
+        break;
     }
+
+    descriptor = -1;
 }
 
 void File::read(void *buffer, const size_t size) const
@@ -314,8 +374,47 @@ void File::write(const void *buffer, const size_t size) const
     }
 }
 
-void File::copyTo(const std::string& dest) const
+File File::copyTo(const std::string& destDir)
 {
+    const std::string& filename = getPath();
+    File destFile(destDir);
+    if (destFile.exists()) {
+        destFile = destDir + "/" + getName();
+    }
+
+    if (isDirectory()) {
+        DirectoryIterator iter(filename), end;
+        destFile.makeDirectory(false, getUid(), getGid());
+
+        while (iter != end) {
+            iter->copyTo(destFile.getPath());
+            ++iter;
+        }
+
+        try {
+            Smack::setTransmute(destFile, Smack::getTransmute(*this));
+        } catch (runtime::Exception &e) {}
+    } else {
+        open(O_RDONLY);
+        destFile.open(O_WRONLY | O_CREAT, getMode());
+        ::sendfile(destFile.descriptor, descriptor, 0, size());
+        destFile.close();
+        close();
+    }
+
+    try {
+        Smack::setAccess(destFile, Smack::getAccess(*this));
+    } catch (runtime::Exception &e) {}
+
+    try {
+        Smack::setExecute(destFile, Smack::getExecute(*this));
+    } catch (runtime::Exception &e) {}
+
+    try {
+        Smack::setMmap(destFile, Smack::getMmap(*this));
+    } catch (runtime::Exception &e) {}
+
+    return destFile;
 }
 
 void File::moveTo(const std::string& dest)
index 035e72f..3211372 100644 (file)
@@ -62,6 +62,11 @@ public:
         return pathname;
     }
 
+    const std::string getFilename() const
+    {
+        return pathname.substr(pathname.rfind('/') + 1);
+    }
+
 private:
     Path& assign(const Path& path);
     Path& assign(const std::string& path);
@@ -125,12 +130,19 @@ public:
     bool isDevice() const;
     bool isHidden() const;
 
+    mode_t getMode() const;
+    uid_t getUid() const;
+    gid_t getGid() const;
+
+    size_t size() const;
+
     void create(mode_t mode);
     void open(int flags);
+    void open(int flags, mode_t mode);
     void read(void *buffer, const size_t size) const;
     void write(const void *buffer, const size_t size) const;
     void close();
-    void copyTo(const std::string& pathname) const;
+    File copyTo(const std::string& pathname);
     void moveTo(const std::string& pathname);
     void renameTo(const std::string& pathname);
     void remove(bool recursive = false);
@@ -150,6 +162,11 @@ public:
         return path.getPathname();
     }
 
+    const std::string getName() const
+    {
+        return path.getFilename();
+    }
+
 private:
     int descriptor;
     Path path;
index 363786a..b2c2871 100644 (file)
@@ -90,7 +90,7 @@ std::string Smack::get(File& file, const char* xattr)
     char* plabel;
     std::string label;
     if (::smack_new_label_from_path(file.getPath().c_str(),
-                                    xattr, 0, &plabel) != 0) {
+                                    xattr, 0, &plabel) < 0) {
         throw runtime::Exception("Getting smack label error");
     }
 
index e02ee11..fac3bff 100644 (file)
@@ -296,10 +296,8 @@ void initializeCreatedZoneList() {
         runtime::DirectoryIterator iter(manifestDir), end;
 
         while (iter != end) {
-            const std::string& path = iter->getPath();
-            size_t namePos = path.rfind('/') + 1;
-            size_t extPos = path.rfind(".xml");
-            const std::string& name(path.substr(namePos, extPos - namePos));
+            const std::string& file = iter->getName();
+            const std::string& name(file.substr(0, file.rfind(".xml")));
             createdZoneList.push_back(name);
             ++iter;
         }