about summary refs log tree commit diff
path: root/src/misc
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2019-07-30 23:48:25 -0400
committerRich Felker <dalias@aerifal.cx>2019-07-31 20:21:04 -0400
commit2e554617e5a6a41bf3f6c6306c753cd53abf728c (patch)
tree9f87293ec82b2ab72551371e8620d2908e22329e /src/misc
parent51fd67fcbfa598e2fe1885b517451b84c0bfe3b7 (diff)
downloadmusl-2e554617e5a6a41bf3f6c6306c753cd53abf728c.tar.gz
musl-2e554617e5a6a41bf3f6c6306c753cd53abf728c.tar.xz
musl-2e554617e5a6a41bf3f6c6306c753cd53abf728c.zip
ioctl: add fallback for new time64 SIOCGSTAMP[NS]
without this, the SIOCGSTAMP and SIOCGSTAMPNS ioctl commands, for
obtaining timestamps, would stop working on pre-5.1 kernels after
time_t is switched to 64-bit and their values are changed to the new
time64 versions.

new code is written such that it's statically unreachable on 64-bit
archs, and on existing 32-bit archs until the macro values are changed
to activate 64-bit time_t.
Diffstat (limited to 'src/misc')
-rw-r--r--src/misc/ioctl.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/src/misc/ioctl.c b/src/misc/ioctl.c
index 5a41f0e8..6f31d4bc 100644
--- a/src/misc/ioctl.c
+++ b/src/misc/ioctl.c
@@ -1,5 +1,8 @@
 #include <sys/ioctl.h>
 #include <stdarg.h>
+#include <errno.h>
+#include <time.h>
+#include <sys/time.h>
 #include "syscall.h"
 
 int ioctl(int fd, int req, ...)
@@ -9,5 +12,25 @@ int ioctl(int fd, int req, ...)
 	va_start(ap, req);
 	arg = va_arg(ap, void *);
 	va_end(ap);
-	return syscall(SYS_ioctl, fd, req, arg);
+	int r = __syscall(SYS_ioctl, fd, req, arg);
+	if (r==-ENOTTY) switch (req) {
+	case SIOCGSTAMP:
+	case SIOCGSTAMPNS:
+		if (SIOCGSTAMP==SIOCGSTAMP_OLD) break;
+		if (req==SIOCGSTAMP) req=SIOCGSTAMP_OLD;
+		if (req==SIOCGSTAMPNS) req=SIOCGSTAMPNS_OLD;
+		long t32[2];
+		r = __syscall(SYS_ioctl, fd, req, t32);
+		if (r<0) break;
+		if (req==SIOCGSTAMP_OLD) {
+			struct timeval *tv = arg;
+			tv->tv_sec = t32[0];
+			tv->tv_usec = t32[1];
+		} else {
+			struct timespec *ts = arg;
+			ts->tv_sec = t32[0];
+			ts->tv_nsec = t32[1];
+		}
+	}
+	return __syscall_ret(r);
 }