Dan Kegel : cmd: mkdir: Set errorlevel and output error message if final directory already exists.

Alexandre Julliard julliard at winehq.org
Wed Aug 3 12:48:14 CDT 2011


Module: wine
Branch: master
Commit: 6990cdfe96cb2f0d62017ba323009e83629d284a
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=6990cdfe96cb2f0d62017ba323009e83629d284a

Author: Dan Kegel <dank at kegel.com>
Date:   Tue Aug  2 12:35:36 2011 -0700

cmd: mkdir: Set errorlevel and output error message if final directory already exists.

---

 programs/cmd/builtins.c                  |   73 +++++++++++++-----------------
 programs/cmd/tests/test_builtins.cmd     |    5 ++
 programs/cmd/tests/test_builtins.cmd.exp |   12 +++--
 3 files changed, 44 insertions(+), 46 deletions(-)

diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
index 7e5ceaf..09c166f 100644
--- a/programs/cmd/builtins.c
+++ b/programs/cmd/builtins.c
@@ -473,54 +473,45 @@ void WCMD_copy (void) {
 /****************************************************************************
  * WCMD_create_dir
  *
- * Create a directory.
+ * Create a directory (and, if needed, any intermediate directories).
  *
- * this works recursively. so mkdir dir1\dir2\dir3 will create dir1 and dir2 if
- * they do not already exist.
+ * Modifies its argument by replacing slashes temporarily with nulls.
  */
 
 static BOOL create_full_path(WCHAR* path)
 {
-    int len;
-    WCHAR *new_path;
-    BOOL ret = TRUE;
-
-    new_path = HeapAlloc(GetProcessHeap(),0,(strlenW(path)+1) * sizeof(WCHAR));
-    strcpyW(new_path,path);
-
-    while ((len = strlenW(new_path)) && new_path[len - 1] == '\\')
-        new_path[len - 1] = 0;
-
-    while (!CreateDirectoryW(new_path,NULL))
-    {
-        WCHAR *slash;
-        DWORD last_error = GetLastError();
-        if (last_error == ERROR_ALREADY_EXISTS)
-            break;
-
-        if (last_error != ERROR_PATH_NOT_FOUND)
-        {
-            ret = FALSE;
-            break;
+    WCHAR *p, *start;
+
+    /* don't mess with drive letter portion of path, if any */
+    start = path;
+    if (path[1] == ':')
+        start = path+2;
+
+    /* Strip trailing slashes. */
+    for (p = path + strlenW(path) - 1; p != start && *p == '\\'; p--)
+        *p = 0;
+
+    /* Step through path, creating intermediate directories as needed. */
+    /* First component includes drive letter, if any. */
+    p = start;
+    for (;;) {
+        DWORD rv;
+        /* Skip to end of component */
+        while (*p == '\\') p++;
+        while (*p && *p != '\\') p++;
+        if (!*p) {
+            /* path is now the original full path */
+            return CreateDirectoryW(path, NULL);
         }
-
-        if (!(slash = strrchrW(new_path,'\\')) && ! (slash = strrchrW(new_path,'/')))
-        {
-            ret = FALSE;
-            break;
-        }
-
-        len = slash - new_path;
-        new_path[len] = 0;
-        if (!create_full_path(new_path))
-        {
-            ret = FALSE;
-            break;
-        }
-        new_path[len] = '\\';
-    }
-    HeapFree(GetProcessHeap(),0,new_path);
-    return ret;
+        /* Truncate path, create intermediate directory, and restore path */
+        *p = 0;
+        rv = CreateDirectoryW(path, NULL);
+        *p = '\\';
+        if (!rv && GetLastError() != ERROR_ALREADY_EXISTS)
+            return FALSE;
+    }
+    /* notreached */
+    return FALSE;
 }
 
 void WCMD_create_dir (WCHAR *command) {
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd
index 2cbff33..2321e12 100644
--- a/programs/cmd/tests/test_builtins.cmd
+++ b/programs/cmd/tests/test_builtins.cmd
@@ -518,6 +518,11 @@ if exist foobar (echo foobar created) else echo foobar not created!
 if exist bar\baz (echo bar\baz created) else echo bar\baz not created!
 cd ..
 rd /s/q foobaz
+call :setError 0
+mkdir foo\*
+echo mkdir foo\* errorlevel %ErrorLevel%
+if exist foo (rmdir foo & echo ok, foo created
+) else ( echo bad, foo not created )
 
 echo ----------- Testing rmdir -----------
 call :setError 0
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp
index f64150d..c430883 100644
--- a/programs/cmd/tests/test_builtins.cmd.exp
+++ b/programs/cmd/tests/test_builtins.cmd.exp
@@ -264,14 +264,14 @@ del /q * succeeded on file2.dat
 ----------- Testing mkdir -----------
 0
 0
- at todo_wine@1
- at todo_wine@1
+1
+1
 0
 0
 0
 0
 0
- at todo_wine@1
+1
 0
 0
 0
@@ -280,13 +280,15 @@ dir created
 mkdir ? gives errorlevel 1
 mkdir ?\foo gives errorlevel 1
 mkdir foo\? gives errorlevel 1
- at todo_wine@ok, foo created
+ok, foo created
 mkdir foo\bar\? gives errorlevel 1
- at todo_wine@ok, foo\bar created
+ok, foo\bar created
 foo created
 bar created
 foobar created
 bar\baz created
+mkdir foo\* errorlevel 1
+ok, foo created
 ----------- Testing rmdir -----------
 0
 dir removed




More information about the wine-cvs mailing list