From 4ea0bcb9229fe12e0c428659d76934351b821872 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 14 Apr 2023 16:29:08 +0900 Subject: [PATCH] chase: CHASE_MKDIR_0755 requires CHASE_NONEXISTENT and/or CHASE_PARENT When CHASE_MKDIR_0755 is specified without CHASE_NONEXISTENT and CHASE_PARENT, then chase() succeeds only when the file specified by the path already exists, and in that case, chase() does not create any parent directories, and CHASE_MKDIR_0755 is meaningless. Let's mention that CHASE_MKDIR_0755 needs to be specified with CHASE_NONEXISTENT or CHASE_PARENT, and adds a assertion about that. --- src/basic/chase.c | 1 + src/basic/chase.h | 10 ++++++++-- src/test/test-chase.c | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/basic/chase.c b/src/basic/chase.c index f167a439adf..eb4bda07a6f 100644 --- a/src/basic/chase.c +++ b/src/basic/chase.c @@ -85,6 +85,7 @@ int chaseat(int dir_fd, const char *path, ChaseFlags flags, char **ret_path, int assert(!FLAGS_SET(flags, CHASE_PREFIX_ROOT)); assert(!FLAGS_SET(flags, CHASE_STEP|CHASE_EXTRACT_FILENAME)); assert(!FLAGS_SET(flags, CHASE_TRAIL_SLASH|CHASE_EXTRACT_FILENAME)); + assert(!FLAGS_SET(flags, CHASE_MKDIR_0755) || (flags & (CHASE_NONEXISTENT | CHASE_PARENT)) != 0); assert(dir_fd >= 0 || dir_fd == AT_FDCWD); /* Either the file may be missing, or we return an fd to the final object, but both make no sense */ diff --git a/src/basic/chase.h b/src/basic/chase.h index 7e9ebe0685d..40121f7d70c 100644 --- a/src/basic/chase.h +++ b/src/basic/chase.h @@ -24,8 +24,14 @@ typedef enum ChaseFlags { * full path is still stored in ret_path and only the returned * file descriptor will point to the parent directory. Note that * the result path is the root or '.', then the file descriptor - * also points to the result path even if this flag is set. */ - CHASE_MKDIR_0755 = 1 << 11, /* Create any missing parent directories in the given path. */ + * also points to the result path even if this flag is set. + * When this specified, chase() will succeed with 1 even if the + * file points to the last path component does not exist. */ + CHASE_MKDIR_0755 = 1 << 11, /* Create any missing parent directories in the given path. This + * needs to be set with CHASE_NONEXISTENT and/or CHASE_PARENT. + * Note, chase_and_open() or friends always add CHASE_PARENT flag + * when internally call chase(), hence CHASE_MKDIR_0755 can be + * safely set without CHASE_NONEXISTENT and CHASE_PARENT. */ CHASE_EXTRACT_FILENAME = 1 << 12, /* Only return the last component of the resolved path */ } ChaseFlags; diff --git a/src/test/test-chase.c b/src/test/test-chase.c index dee781929d9..1e98f5c6ed2 100644 --- a/src/test/test-chase.c +++ b/src/test/test-chase.c @@ -509,7 +509,7 @@ TEST(chaseat) { assert_se(streq(result, "q")); result = mfree(result); - assert_se(chaseat(tfd, "i/../p", CHASE_MKDIR_0755, NULL, NULL) == -ENOENT); + assert_se(chaseat(tfd, "i/../p", CHASE_MKDIR_0755|CHASE_NONEXISTENT, NULL, NULL) == -ENOENT); /* Test CHASE_FILENAME */ -- 2.47.3