mirror of
https://github.com/systemd/systemd.git
synced 2025-01-09 01:18:19 +03:00
basic/mkdir: use timespec_store instead of _nsec for mkdir_p_root_full
Follow-up for 34c3d57474
O_RDONLY is dropped when O_DIRECTORY is specified, since
it's unnecessary and even arguably confusing here, as
the dir is modified.
This commit is contained in:
parent
026335e9aa
commit
158681f0f9
@ -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;
|
||||
|
||||
|
@ -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_OK(mkdtemp_malloc("/tmp/test-mkdir-XXXXXX", &tmp));
|
||||
|
||||
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);
|
||||
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_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);
|
||||
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_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_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);
|
||||
|
Loading…
Reference in New Issue
Block a user