]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Change File_CreateDirectoryHierarchy to enable "undo"
authorVMware, Inc <>
Tue, 13 Mar 2012 20:10:34 +0000 (13:10 -0700)
committerDmitry Torokhov <dtor@vmware.com>
Wed, 14 Mar 2012 16:43:26 +0000 (09:43 -0700)
When calling File_CreateDirectoryHierarchy, there was no way to know
what was actually created by the call and what wasn't. This meant that
trying to be a good neighbor and clean up after ourselves if whatever we
wanted the directory for failed (or was cancelled) wasn't possible.

This change adds an optional OUT parameter to that gets set to the
top-most directory which was actually created by the call. If the caller
then wants to clean up, they can pass that into
File_DeleteDirectoryTree.

Signed-off-by: Dmitry Torokhov <dtor@vmware.com>
open-vm-tools/lib/file/file.c
open-vm-tools/lib/include/file.h
open-vm-tools/services/plugins/vix/vixTools.c

index 8eb280b919b06ab8e42dee3e2fcca065b3e1d524..dc6b437df084bd5a055d64c4d5146e65fcaec1fa 100644 (file)
@@ -1396,7 +1396,7 @@ File_MoveTree(ConstUnicode srcName,   // IN:
          int err = Err_Errno();
 
          if (ENOENT == err) {
-            if (!File_CreateDirectoryHierarchy(dstName)) {
+            if (!File_CreateDirectoryHierarchy(dstName, NULL)) {
                Msg_Append(MSGID(File.MoveTree.dst.couldntCreate)
                           "Could not create '%s'.\n\n", UTF8(dstName));
 
@@ -1649,10 +1649,19 @@ File_GetSizeByPath(ConstUnicode pathName)  // IN:
  * File_CreateDirectoryHierarchy --
  *
  *      Create a directory including any parents that don't already exist.
+ *      Returns the topmost directory which was created, to allow calling code
+ *      to remove it after in case later operations fail.
  *
  * Results:
  *      TRUE on success, FALSE on failure.
  *
+ *      If topmostCreated is not NULL, it returns the result of the hierarchy
+ *      creation. If no directory was created, *topmostCreated is set to NULL.
+ *      Otherwise *topmostCreated is set to the topmost directory which was
+ *      created. *topmostCreated is set even in case of failure.
+ *
+ *      The caller most Unicode_Free the resulting string.
+ *
  * Side effects:
  *      Only the obvious.
  *
@@ -1660,12 +1669,17 @@ File_GetSizeByPath(ConstUnicode pathName)  // IN:
  */
 
 Bool
-File_CreateDirectoryHierarchy(ConstUnicode pathName)  // IN:
+File_CreateDirectoryHierarchy(ConstUnicode pathName,   // IN:
+                              Unicode *topmostCreated) // OUT:
 {
    Unicode volume;
    UnicodeIndex index;
    UnicodeIndex length;
 
+   if (topmostCreated != NULL) {
+      *topmostCreated = NULL;
+   }
+
    if (pathName == NULL) {
       return TRUE;
    }
@@ -1700,22 +1714,31 @@ File_CreateDirectoryHierarchy(ConstUnicode pathName)  // IN:
 
       index = FileFirstSlashIndex(pathName, index + 1);
 
-      if (index == UNICODE_INDEX_NOT_FOUND) {
-         break;
-      }
+      temp = Unicode_Substr(pathName, 0, (index == UNICODE_INDEX_NOT_FOUND) ? -1 : index);
 
-      temp = Unicode_Substr(pathName, 0, index);
-
-      failed = !File_IsDirectory(temp) && !File_CreateDirectory(temp);
+      if (File_IsDirectory(temp)) {
+         failed = FALSE;
+      } else {
+         failed = !File_CreateDirectory(temp);
+         if (!failed && topmostCreated != NULL && *topmostCreated == NULL) {
+            *topmostCreated = temp;
+            temp = NULL;
+         }
+      }
 
       Unicode_Free(temp);
 
       if (failed) {
          return FALSE;
       }
+
+      if (index == UNICODE_INDEX_NOT_FOUND) {
+         break;
+      }
+
    }
 
-   return File_IsDirectory(pathName) || File_CreateDirectory(pathName);
+   return TRUE;
 }
 
 
index 39e54d0f9694f62be012c87d92dd5f3597fdd113..11b0733f46fffefa5af32c2b3e57881f4555d85e 100644 (file)
@@ -158,7 +158,8 @@ Bool File_EnsureDirectory(ConstUnicode pathName);
 
 Bool File_DeleteEmptyDirectory(ConstUnicode pathName);
 
-Bool File_CreateDirectoryHierarchy(ConstUnicode pathName);
+Bool File_CreateDirectoryHierarchy(ConstUnicode pathName,
+                                   Unicode *topmostCreated);
 
 Bool File_DeleteDirectoryTree(ConstUnicode pathName);
 
index cc64d94e7613b4953b9a6dfd6224306fa1951bdf..0ddef806d4bea1d821494714a087fe0e6eae005c 100644 (file)
@@ -5534,7 +5534,7 @@ VixToolsCreateDirectory(VixCommandRequestHeader *requestMsg)  // IN
    }
 
    if (createParentDirectories) {
-      if (!(File_CreateDirectoryHierarchy(dirPathName))) {
+      if (!(File_CreateDirectoryHierarchy(dirPathName, NULL))) {
          err = FoundryToolsDaemon_TranslateSystemErr();
          goto abort;
       }