You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ji...@apache.org on 2016/03/28 21:59:45 UTC

[5/8] mesos git commit: Extended `os::rmdir` in stout to support preserving the root directory.

Extended `os::rmdir` in stout to support preserving the root directory.

This allows `os::rmdir("/x")` to optionally remove all the child files
and directories of the root directory "/x", but preserve "/x" itself.

Review: https://reviews.apache.org/r/45120/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/abf27626
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/abf27626
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/abf27626

Branch: refs/heads/master
Commit: abf27626ea6024c45d7b27fb3bfa63fe99048031
Parents: 6fbc13f
Author: Neil Conway <ne...@gmail.com>
Authored: Mon Mar 28 12:58:35 2016 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Mon Mar 28 12:58:35 2016 -0700

----------------------------------------------------------------------
 .../stout/include/stout/os/posix/rmdir.hpp      | 18 +++++++++++---
 .../stout/include/stout/os/windows/rmdir.hpp    | 21 ++++++++++------
 .../3rdparty/stout/tests/os/rmdir_tests.cpp     | 25 +++++++++++++++++++-
 3 files changed, 53 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/abf27626/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/rmdir.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/rmdir.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/rmdir.hpp
index 44a59b8..a6d3b57 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/rmdir.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/posix/rmdir.hpp
@@ -26,11 +26,17 @@
 
 namespace os {
 
-// By default, recursively deletes a directory akin to: 'rm -r'. If the
-// programmer sets recursive to false, it deletes a directory akin to: 'rmdir'.
+// By default, recursively deletes a directory akin to: 'rm -r'. If
+// `recursive` is false, it deletes a directory akin to: 'rmdir'. In
+// recursive mode, `removeRoot` can be set to false to enable removing
+// all the files and directories beneath the given root directory, but
+// not the root directory itself.
 // Note that this function expects an absolute path.
 #ifndef __sun // FTS is not available on Solaris.
-inline Try<Nothing> rmdir(const std::string& directory, bool recursive = true)
+inline Try<Nothing> rmdir(
+    const std::string& directory,
+    bool recursive = true,
+    bool removeRoot = true)
 {
   if (!recursive) {
     if (::rmdir(directory.c_str()) < 0) {
@@ -58,6 +64,12 @@ inline Try<Nothing> rmdir(const std::string& directory, bool recursive = true)
     while ((node = fts_read(tree)) != NULL) {
       switch (node->fts_info) {
         case FTS_DP:
+          // Don't remove the root of the traversal of `removeRoot`
+          // is false.
+          if (!removeRoot && node->fts_level == FTS_ROOTLEVEL) {
+            continue;
+          }
+
           if (::rmdir(node->fts_path) < 0 && errno != ENOENT) {
             Error error = ErrnoError();
             fts_close(tree);

http://git-wip-us.apache.org/repos/asf/mesos/blob/abf27626/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/rmdir.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/rmdir.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/rmdir.hpp
index 4e3dd0f..dd5cc69 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/rmdir.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/os/windows/rmdir.hpp
@@ -29,7 +29,8 @@ namespace internal {
 
 // Recursive version of `RemoveDirectory`. NOTE: unlike `rmdir`, this requires
 // Windows-formatted paths, and therefore should be in the `internal` namespace.
-inline Try<Nothing> recursive_remove_directory(const std::string& path)
+inline Try<Nothing> recursive_remove_directory(
+    const std::string& path, bool removeRoot)
 {
   // Appending a slash here if the path doesn't already have one simplifies
   // path join logic later, because (unlike Unix) Windows doesn't like double
@@ -90,8 +91,8 @@ inline Try<Nothing> recursive_remove_directory(const std::string& path)
     }
   } while (FindNextFile(search_handle.get(), &found));
 
-  // Finally, remove current directory.
-  if (::_rmdir(current_path.c_str()) == -1) {
+  // Finally, remove current directory unless `removeRoot` is disabled.
+  if (removeRoot && ::_rmdir(current_path.c_str()) == -1) {
     return ErrnoError(
         "`os::internal::recursive_remove_directory` attempted to delete file "
         "'" + current_path + "', but failed");
@@ -103,10 +104,16 @@ inline Try<Nothing> recursive_remove_directory(const std::string& path)
 } // namespace internal {
 
 
-// By default, recursively deletes a directory akin to: 'rm -r'. If the
-// programmer sets recursive to false, it deletes a directory akin to: 'rmdir'.
+// By default, recursively deletes a directory akin to: 'rm -r'. If
+// `recursive` is false, it deletes a directory akin to: 'rmdir'. In
+// recursive mode, `removeRoot` can be set to false to enable removing
+// all the files and directories beneath the given root directory, but
+// not the root directory itself.
 // Note that this function expects an absolute path.
-inline Try<Nothing> rmdir(const std::string& directory, bool recursive = true)
+inline Try<Nothing> rmdir(
+    const std::string& directory,
+    bool recursive = true,
+    bool removeRoot = true)
 {
   // Canonicalize the path to Windows style for the call to
   // `recursive_remove_directory`.
@@ -127,7 +134,7 @@ inline Try<Nothing> rmdir(const std::string& directory, bool recursive = true)
       return Nothing();
     }
   } else {
-    return os::internal::recursive_remove_directory(root.get());
+    return os::internal::recursive_remove_directory(root.get(), removeRoot);
   }
 }
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/abf27626/3rdparty/libprocess/3rdparty/stout/tests/os/rmdir_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/os/rmdir_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/os/rmdir_tests.cpp
index 5466991..cc92953 100644
--- a/3rdparty/libprocess/3rdparty/stout/tests/os/rmdir_tests.cpp
+++ b/3rdparty/libprocess/3rdparty/stout/tests/os/rmdir_tests.cpp
@@ -143,7 +143,7 @@ TEST_F(RmdirTest, TrivialFailToRemoveInvalidPath)
 }
 
 
-TEST_F(RmdirTest, FailTRemoveNestedInvalidPath)
+TEST_F(RmdirTest, FailToRemoveNestedInvalidPath)
 {
   const string tmpdir = os::getcwd();
   hashset<string> expectedRootListing = EMPTY;
@@ -273,3 +273,26 @@ TEST_F(RmdirTest, RemoveDirectoryWithSymbolicLinkTargetFile)
   // Verify that the target file is not removed.
   ASSERT_TRUE(os::exists(targetFile));
 }
+
+
+// This tests that when appropriately instructed, `rmdir` can remove
+// the files and subdirectories that appear in a directory but
+// preserve the directory itself.
+TEST_F(RmdirTest, RemoveDirectoryButPreserveRoot)
+{
+  const string newDirectory = path::join(os::getcwd(), "newDirectory");
+  ASSERT_SOME(os::mkdir(newDirectory));
+
+  const string subDirectory = path::join(newDirectory, "subDirectory");
+  ASSERT_SOME(os::mkdir(subDirectory));
+
+  const string file1 = path::join(newDirectory, "file1");
+  ASSERT_SOME(os::touch(file1));
+
+  const string file2 = path::join(subDirectory, "file2");
+  ASSERT_SOME(os::touch(file2));
+
+  EXPECT_SOME(os::rmdir(newDirectory, true, false));
+  EXPECT_TRUE(os::exists(newDirectory));
+  EXPECT_EQ(EMPTY, listfiles(newDirectory));
+}