]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic/mkdir: use timespec_store instead of _nsec for mkdir_p_root_full
authorMike Yuan <me@yhndnzj.com>
Tue, 7 May 2024 12:13:55 +0000 (20:13 +0800)
committerMike Yuan <me@yhndnzj.com>
Tue, 7 May 2024 16:18:27 +0000 (00:18 +0800)
Follow-up for 34c3d574742e867ef97e79509e4051a82f1b7d9b

O_RDONLY is dropped when O_DIRECTORY is specified, since
it's unnecessary and even arguably confusing here, as
the dir is modified.

src/basic/mkdir.c
src/test/test-mkdir.c

index c378f896041fe5101e996f58595f3aa5e1325175..20329e04c2dba17745352c67d35b6c0ea5f4f6e1 100644 (file)
@@ -209,6 +209,8 @@ int mkdir_p_root_full(const char *root, const char *p, uid_t uid, gid_t gid, mod
         _cleanup_close_ int dfd = -EBADF;
         int r;
 
+        assert(p);
+
         r = path_extract_directory(p, &pp);
         if (r == -EDESTADDRREQ) {
                 /* only fname is passed, no prefix to operate on */
@@ -226,7 +228,7 @@ int mkdir_p_root_full(const char *root, const char *p, uid_t uid, gid_t gid, mod
                 if (r < 0)
                         return r;
 
-                dfd = chase_and_open(pp, root, CHASE_PREFIX_ROOT, O_RDONLY|O_CLOEXEC|O_DIRECTORY, NULL);
+                dfd = chase_and_open(pp, root, CHASE_PREFIX_ROOT, O_CLOEXEC|O_DIRECTORY, NULL);
                 if (dfd < 0)
                         return dfd;
         }
@@ -241,25 +243,22 @@ int mkdir_p_root_full(const char *root, const char *p, uid_t uid, gid_t gid, mod
                 r = btrfs_subvol_make_fallback(dfd, bn, m);
         else
                 r = RET_NERRNO(mkdirat(dfd, bn, m));
-        if (r < 0) {
-                if (r == -EEXIST)
-                        return 0;
-
+        if (r == -EEXIST)
+                return 0;
+        if (r < 0)
                 return r;
-        }
 
         if (ts == USEC_INFINITY && !uid_is_valid(uid) && !gid_is_valid(gid))
                 return 1;
 
-        _cleanup_close_ int nfd = -EBADF;
-        nfd = openat(dfd, bn, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOFOLLOW);
+        _cleanup_close_ int nfd = openat(dfd, bn, O_CLOEXEC|O_DIRECTORY|O_NOFOLLOW);
         if (nfd < 0)
                 return -errno;
 
         if (ts != USEC_INFINITY) {
                 struct timespec tspec;
+                timespec_store(&tspec, ts);
 
-                timespec_store_nsec(&tspec, ts);
                 if (futimens(dfd, (const struct timespec[2]) { { .tv_nsec = UTIME_OMIT }, tspec }) < 0)
                         return -errno;
 
index fcb8fc7a6b4749de85101e34dd42cb9f08cce72e..ef00729c08ba75470b6515f6740a42d266dbc916 100644 (file)
@@ -143,26 +143,26 @@ TEST(mkdir_p_root_full) {
         _cleanup_free_ char *p = NULL;
         struct stat st;
 
-        assert_se(mkdtemp_malloc("/tmp/test-mkdir-XXXXXX", &tmp) >= 0);
-
-        assert_se(p = path_join(tmp, "foo"));
-        assert_se(mkdir_p_root_full(tmp, "/foo", UID_INVALID, GID_INVALID, 0755, 1234, NULL) >= 0);
-        assert_se(is_dir(p, false) > 0);
-        assert_se(is_dir(p, true) > 0);
-        assert_se(stat(p, &st) >= 0);
-        assert_se(st.st_mtim.tv_nsec == 1234);
-        assert_se(st.st_atim.tv_nsec == 1234);
-
-        p = mfree(p);
-        assert_se(p = path_join(tmp, "dir-not-exists/foo"));
-        assert_se(mkdir_p_root_full(tmp, "/dir-not-exists/foo", UID_INVALID, GID_INVALID, 0755, 5678, NULL) >= 0);
-        assert_se(is_dir(p, false) > 0);
-        assert_se(is_dir(p, true) > 0);
-        p = mfree(p);
-        assert_se(p = path_join(tmp, "dir-not-exists"));
-        assert_se(stat(p, &st) >= 0);
-        assert_se(st.st_mtim.tv_nsec == 5678);
-        assert_se(st.st_atim.tv_nsec == 5678);
+        ASSERT_OK(mkdtemp_malloc("/tmp/test-mkdir-XXXXXX", &tmp));
+
+        ASSERT_NOT_NULL(p = path_join(tmp, "foo"));
+        ASSERT_OK(mkdir_p_root_full(tmp, "/foo", UID_INVALID, GID_INVALID, 0755, 2 * USEC_PER_SEC, NULL));
+        ASSERT_GT(is_dir(p, false), 0);
+        ASSERT_GT(is_dir(p, true), 0);
+        ASSERT_OK_ERRNO(stat(p, &st));
+        ASSERT_EQ(st.st_mtim.tv_sec, 2);
+        ASSERT_EQ(st.st_atim.tv_sec, 2);
+
+        p = mfree(p);
+        ASSERT_NOT_NULL(p = path_join(tmp, "dir-not-exists/foo"));
+        ASSERT_OK(mkdir_p_root_full(NULL, p, UID_INVALID, GID_INVALID, 0755, 90 * USEC_PER_HOUR, NULL));
+        ASSERT_GT(is_dir(p, false), 0);
+        ASSERT_GT(is_dir(p, true), 0);
+        p = mfree(p);
+        ASSERT_NOT_NULL(p = path_join(tmp, "dir-not-exists"));
+        ASSERT_OK_ERRNO(stat(p, &st));
+        ASSERT_EQ(st.st_mtim.tv_sec, 90 * 60 * 60);
+        ASSERT_EQ(st.st_atim.tv_sec, 90 * 60 * 60);
 }
 
 DEFINE_TEST_MAIN(LOG_DEBUG);