summaryrefslogtreecommitdiff
path: root/src/misc/ioctl.c
blob: 6f31d4bc91cf26a68b9bc799eb2eb0e636b8bce7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#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, ...)
{
	void *arg;
	va_list ap;
	va_start(ap, req);
	arg = va_arg(ap, void *);
	va_end(ap);
	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);
}