diff options
| author | Florian Weimer <fweimer@redhat.com> | 2024-12-19 20:56:44 +0100 |
|---|---|---|
| committer | Florian Weimer <fweimer@redhat.com> | 2024-12-19 21:21:30 +0100 |
| commit | 70d083630563831e7069ad412cd3ab0b33638e92 (patch) | |
| tree | 19489200ed8cdda06adac90a48b3b602bdd0fefe | |
| parent | 30d3fd7f4f4bc8f767d73ad4e4b005c1bd234310 (diff) | |
| download | glibc-70d083630563831e7069ad412cd3ab0b33638e92.tar.xz glibc-70d083630563831e7069ad412cd3ab0b33638e92.zip | |
Linux: Accept null arguments for utimensat pathname
This matches kernel behavior. With this change, it is possible
to use utimensat as a replacement for the futimens interface,
similar to what glibc does internally.
Reviewed-by: Paul Eggert <eggert@cs.ucla.edu>
| -rw-r--r-- | io/sys/stat.h | 4 | ||||
| -rw-r--r-- | io/tst-utimensat.c | 32 | ||||
| -rw-r--r-- | sysdeps/unix/sysv/linux/utimensat.c | 3 |
3 files changed, 34 insertions, 5 deletions
diff --git a/io/sys/stat.h b/io/sys/stat.h index 0e4edb483d..dd96b88d0f 100644 --- a/io/sys/stat.h +++ b/io/sys/stat.h @@ -433,13 +433,13 @@ extern int mkfifoat (int __fd, const char *__path, __mode_t __mode) extern int utimensat (int __fd, const char *__path, const struct timespec __times[2], int __flags) - __THROW __nonnull ((2)); + __THROW; # else # ifdef __REDIRECT_NTH extern int __REDIRECT_NTH (utimensat, (int fd, const char *__path, const struct timespec __times[2], int flags), - __utimensat64) __nonnull ((2)); + __utimensat64); # else # define utimensat __utimensat64 # endif diff --git a/io/tst-utimensat.c b/io/tst-utimensat.c index 2a756d7b07..43786817b5 100644 --- a/io/tst-utimensat.c +++ b/io/tst-utimensat.c @@ -39,6 +39,38 @@ test_utimesat_helper (const char *testfile, int fd, const char *testlink, TEST_COMPARE (st.stx_mtime.tv_sec, ts[1].tv_sec); } + /* Alter the timestamp using a NULL path. */ + { + struct timespec ts1[2] = {ts[0], ts[1]}; + ts1[0].tv_sec ^= 1; + ts1[1].tv_sec ^= 1; + + TEST_VERIFY_EXIT (utimensat (fd, NULL, ts1, 0) == 0); + + struct statx st; + xstatx (fd, "", AT_EMPTY_PATH, STATX_BASIC_STATS, &st); + + /* Check if seconds for atime match */ + TEST_COMPARE (st.stx_atime.tv_sec, ts[0].tv_sec ^ 1); + + /* Check if seconds for mtime match */ + TEST_COMPARE (st.stx_mtime.tv_sec, ts[1].tv_sec ^ 1); + } + + /* And switch it back using a NULL path. */ + { + TEST_VERIFY_EXIT (utimensat (fd, NULL, ts, 0) == 0); + + struct statx st; + xstatx (fd, "", AT_EMPTY_PATH, STATX_BASIC_STATS, &st); + + /* Check if seconds for atime match */ + TEST_COMPARE (st.stx_atime.tv_sec, ts[0].tv_sec); + + /* Check if seconds for mtime match */ + TEST_COMPARE (st.stx_mtime.tv_sec, ts[1].tv_sec); + } + { struct statx stfile_orig; xstatx (AT_FDCWD, testfile, AT_SYMLINK_NOFOLLOW, STATX_BASIC_STATS, diff --git a/sysdeps/unix/sysv/linux/utimensat.c b/sysdeps/unix/sysv/linux/utimensat.c index 991897f50d..f3ba1aa647 100644 --- a/sysdeps/unix/sysv/linux/utimensat.c +++ b/sysdeps/unix/sysv/linux/utimensat.c @@ -75,9 +75,6 @@ int __utimensat64 (int fd, const char *file, const struct __timespec64 tsp64[2], int flags) { - if (file == NULL) - return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL); - return __utimensat64_helper (fd, file, &tsp64[0], flags); } |
