Bug 960046 - [OS.File] makeDir should not fail if the directory is a root. r=Yoric, a=sledru
authorKay Plößer <mail@kay.is>
Thu, 06 Feb 2014 10:05:43 -0500
changeset 176289 f4b5ae829393ea6a10be2af54b8a0eede7d80818
parent 176288 8cb5df1f8bc8cee15cb6bc3f2d76b04d8bf9165e
child 176290 466320bb1b52bc504dbcd41255f4195366e9afb7
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersYoric, sledru
bugs960046
milestone28.0
Bug 960046 - [OS.File] makeDir should not fail if the directory is a root. r=Yoric, a=sledru
toolkit/components/osfile/modules/osfile_unix_front.jsm
toolkit/components/osfile/modules/osfile_win_front.jsm
toolkit/components/osfile/tests/xpcshell/test_makeDir.js
--- a/toolkit/components/osfile/modules/osfile_unix_front.jsm
+++ b/toolkit/components/osfile/modules/osfile_unix_front.jsm
@@ -370,17 +370,17 @@
       * - {bool} ignoreExisting If |false|, throw error if the directory
       * already exists. |true| by default
       */
      File.makeDir = function makeDir(path, options = {}) {
        let omode = options.unixMode !== undefined ? options.unixMode : DEFAULT_UNIX_MODE_DIR;
        let result = UnixFile.mkdir(path, omode);
        if (result == -1) {
          if ((!("ignoreExisting" in options) || options.ignoreExisting) &&
-             ctypes.errno == Const.EEXIST) {
+             (ctypes.errno == Const.EEXIST || ctypes.errno == Const.EISDIR)) {
            return;
          }
          throw new File.Error("makeDir");
        }
      };
 
      /**
       * Copy a file to a destination.
--- a/toolkit/components/osfile/modules/osfile_win_front.jsm
+++ b/toolkit/components/osfile/modules/osfile_win_front.jsm
@@ -436,23 +436,45 @@
       * use the default security descriptor, inherited from the
       * parent directory.
       * - {bool} ignoreExisting If |false|, throw an error if the directory
       * already exists. |true| by default
       */
      File.makeDir = function makeDir(path, options = {}) {
        let security = options.winSecurity || null;
        let result = WinFile.CreateDirectory(path, security);
-       if (!result) {
-         if ((!("ignoreExisting" in options) || options.ignoreExisting) &&
-             ctypes.winLastError == Const.ERROR_ALREADY_EXISTS) {
-           return;
-         }
+
+       if (result) {
+         return;
+       }
+
+       if (("ignoreExisting" in options) && !options.ignoreExisting) {
          throw new File.Error("makeDir");
        }
+
+       if (ctypes.winLastError == Const.ERROR_ALREADY_EXISTS) {
+         return;
+       }
+
+       // If the user has no access, but it's a root directory, no error should be thrown
+       let splitPath = OS.Path.split(path);
+       // Removing last component if it's empty
+       // An empty last component is caused by trailing slashes in path
+       // This is always the case with root directories
+       if( splitPath.components[splitPath.components.length - 1].length === 0 ) {
+         splitPath.components.pop();
+       }
+       // One component and an absolute path implies a directory root.
+       if (ctypes.winLastError == Const.ERROR_ACCESS_DENIED &&
+           splitPath.absolute &&
+           splitPath.components.length === 1 ) {
+         return;
+       }
+
+       throw new File.Error("makeDir");
      };
 
      /**
       * Copy a file to a destination.
       *
       * @param {string} sourcePath The platform-specific path at which
       * the file may currently be found.
       * @param {string} destPath The platform-specific path at which the
--- a/toolkit/components/osfile/tests/xpcshell/test_makeDir.js
+++ b/toolkit/components/osfile/tests/xpcshell/test_makeDir.js
@@ -48,9 +48,27 @@ add_task(function() {
     yield OS.File.makeDir(dir, {ignoreExisting: false});
   } catch (ex) {
     exception = ex;
   }
 
   do_check_true(!!exception);
   do_check_true(exception instanceof OS.File.Error);
   do_check_true(exception.becauseExists);
+
+  // Make a root directory that already exists
+  if (OS.Constants.Win) {
+    dir = "C:\\";
+  } else {
+    dir = "/";
+  }
+
+  yield OS.File.makeDir(dir);
+
+  // Make a normal directory that already exists
+  if (OS.Constants.Win) {
+    dir = "C:\\Program Files";
+  } else {
+    dir = "/tmp";
+  }
+
+  yield OS.File.makeDir(dir);
 });