about summary refs log tree commit diff
path: root/src/stat
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2019-07-27 10:20:01 -0400
committerRich Felker <dalias@aerifal.cx>2019-07-27 13:43:13 -0400
commitcb856a616076c0df27dad7222640814ae58cdc96 (patch)
tree806a00171641329ed75a6ff82ed02f06953426ca /src/stat
parent331993e3fc3623f111d95796d3d7f30b4f6552c1 (diff)
downloadmusl-cb856a616076c0df27dad7222640814ae58cdc96.tar.gz
musl-cb856a616076c0df27dad7222640814ae58cdc96.tar.xz
musl-cb856a616076c0df27dad7222640814ae58cdc96.zip
fix and simplify futimesat fallback in utimensat
previously the fallback wrongly failed with EINVAL rather than ENOSYS
when UTIME_NOW was used with one component but not both. commit
dd5f50da6f6c3df5647e922e47f8568a8896a752 introduced this behavior when
initially adding the fallback support.

instead, detect the case where both are UTIME_NOW early and replace
with a null times pointer; this may improve performance slightly (less
copy from user), and removes the complex logic from the fallback case.
it also makes things slightly simpler for adding time64 code paths.
Diffstat (limited to 'src/stat')
-rw-r--r--src/stat/utimensat.c10
1 files changed, 4 insertions, 6 deletions
diff --git a/src/stat/utimensat.c b/src/stat/utimensat.c
index 159c8be3..49d74c22 100644
--- a/src/stat/utimensat.c
+++ b/src/stat/utimensat.c
@@ -6,6 +6,8 @@
 
 int utimensat(int fd, const char *path, const struct timespec times[2], int flags)
 {
+	if (times && times[0].tv_nsec==UTIME_NOW && times[1].tv_nsec==UTIME_NOW)
+		times = 0;
 	int r = __syscall(SYS_utimensat, fd, path, times, flags);
 #ifdef SYS_futimesat
 	if (r != -ENOSYS || flags) return __syscall_ret(r);
@@ -15,12 +17,8 @@ int utimensat(int fd, const char *path, const struct timespec times[2], int flag
 		tv = tmp;
 		for (i=0; i<2; i++) {
 			if (times[i].tv_nsec >= 1000000000ULL) {
-				if (times[i].tv_nsec == UTIME_NOW &&
-				    times[1-i].tv_nsec == UTIME_NOW) {
-					tv = 0;
-					break;
-				}
-				if (times[i].tv_nsec == UTIME_OMIT)
+				if (times[i].tv_nsec == UTIME_NOW
+				 || times[i].tv_nsec == UTIME_OMIT)
 					return __syscall_ret(-ENOSYS);
 				return __syscall_ret(-EINVAL);
 			}