summaryrefslogtreecommitdiffstats
path: root/tests/xtouch.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2023-10-02 13:09:36 -0400
committerTavian Barnes <tavianator@tavianator.com>2023-10-02 13:09:36 -0400
commitfed31013ebfa6b0c5165f015da5b96ce524224eb (patch)
treeb813c642cfca01be245af82cdf1e903fa2de36f8 /tests/xtouch.c
parent9907004a1bb047e0644bf6d180aeb8b6ac23b1bb (diff)
parent692098fdb922c464949fad7c5b9e36b531ea6f68 (diff)
downloadbfs-fed31013ebfa6b0c5165f015da5b96ce524224eb.tar.xz
Merge branch 'benchmarks'
Diffstat (limited to 'tests/xtouch.c')
-rw-r--r--tests/xtouch.c39
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;
}