about summary refs log tree commit diff
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
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.
-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);
 			}