]> Sergey Matveev's repositories - bfs.git/commitdiff
tests/xtouch: Try creating the immediate parent first
authorTavian Barnes <tavianator@tavianator.com>
Fri, 29 Sep 2023 19:13:41 +0000 (15:13 -0400)
committerTavian Barnes <tavianator@tavianator.com>
Fri, 29 Sep 2023 19:14:40 +0000 (15:14 -0400)
tests/xtouch.c

index 4a02bf30340fe70ba5809a47119d10b83cb110ef..80fad8d094b48adc9c00cf98b782a2f798d2ba6a 100644 (file)
@@ -48,31 +48,40 @@ static int at_flags(const struct args *args) {
 
 /** Create any parent directories of the given path. */
 static int mkdirs(const char *path, mode_t mode) {
-       char *copy = strdup(path);
-       if (!copy) {
-               return -1;
+       int ret = -1;
+       char *dir = xdirname(path);
+       if (!dir) {
+               goto err;
        }
 
-       int ret = -1;
-       char *cur = copy + strspn(copy, "/");
-       while (true) {
-               cur += strcspn(cur, "/");
+       if (strcmp(dir, ".") == 0) {
+               goto done;
+       }
+
+       // Optimistically try the immediate parent first
+       if (mkdir(dir, mode) == 0 || errno == EEXIST) {
+               goto done;
+       }
 
+       // Create the parents one-at-a-time
+       char *cur = dir + strspn(dir, "/");
+       while (*cur) {
+               cur += strcspn(cur, "/");
                char *next = cur + strspn(cur, "/");
-               if (!*next) {
-                       ret = 0;
-                       break;
-               }
 
+               char c = *cur;
                *cur = '\0';
-               if (mkdir(copy, mode) != 0 && errno != EEXIST) {
-                       break;
+               if (mkdir(dir, mode) != 0 && errno != EEXIST) {
+                       goto err;
                }
-               *cur = '/';
+               *cur = c;
                cur = next;
        }
 
-       free(copy);
+done:
+       ret = 0;
+err:
+       free(dir);
        return ret;
 }