diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2023-10-02 13:09:36 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2023-10-02 13:09:36 -0400 |
commit | fed31013ebfa6b0c5165f015da5b96ce524224eb (patch) | |
tree | b813c642cfca01be245af82cdf1e903fa2de36f8 /tests | |
parent | 9907004a1bb047e0644bf6d180aeb8b6ac23b1bb (diff) | |
parent | 692098fdb922c464949fad7c5b9e36b531ea6f68 (diff) | |
download | bfs-fed31013ebfa6b0c5165f015da5b96ce524224eb.tar.xz |
Merge branch 'benchmarks'
Diffstat (limited to 'tests')
-rw-r--r-- | tests/xtouch.c | 39 |
1 files changed, 24 insertions, 15 deletions
diff --git a/tests/xtouch.c b/tests/xtouch.c index 4a02bf3..80fad8d 100644 --- a/tests/xtouch.c +++ b/tests/xtouch.c @@ -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; } |