]>
Commit | Line | Data |
---|---|---|
320054e8 | 1 | #include <sys/socket.h> |
79a9b408 DG |
2 | #include <sys/time.h> |
3 | #include <errno.h> | |
320054e8 DG |
4 | #include "syscall.h" |
5 | ||
6 | int getsockopt(int fd, int level, int optname, void *restrict optval, socklen_t *restrict optlen) | |
7 | { | |
79a9b408 DG |
8 | long tv32[2]; |
9 | struct timeval *tv; | |
10 | ||
11 | int r = __socketcall(getsockopt, fd, level, optname, optval, optlen, 0); | |
12 | ||
13 | if (r==-ENOPROTOOPT) switch (level) { | |
14 | case SOL_SOCKET: | |
15 | switch (optname) { | |
16 | case SO_RCVTIMEO: | |
17 | case SO_SNDTIMEO: | |
18 | if (SO_RCVTIMEO == SO_RCVTIMEO_OLD) break; | |
19 | if (*optlen < sizeof *tv) return __syscall_ret(-EINVAL); | |
20 | if (optname==SO_RCVTIMEO) optname=SO_RCVTIMEO_OLD; | |
21 | if (optname==SO_SNDTIMEO) optname=SO_SNDTIMEO_OLD; | |
22 | r = __socketcall(getsockopt, fd, level, optname, | |
23 | tv32, (socklen_t[]){sizeof tv32}, 0); | |
24 | if (r<0) break; | |
25 | tv = optval; | |
26 | tv->tv_sec = tv32[0]; | |
27 | tv->tv_usec = tv32[1]; | |
28 | *optlen = sizeof *tv; | |
575e1579 DG |
29 | break; |
30 | case SO_TIMESTAMP: | |
31 | case SO_TIMESTAMPNS: | |
32 | if (SO_TIMESTAMP == SO_TIMESTAMP_OLD) break; | |
33 | if (optname==SO_TIMESTAMP) optname=SO_TIMESTAMP_OLD; | |
34 | if (optname==SO_TIMESTAMPNS) optname=SO_TIMESTAMPNS_OLD; | |
35 | r = __socketcall(getsockopt, fd, level, | |
36 | optname, optval, optlen, 0); | |
37 | break; | |
79a9b408 DG |
38 | } |
39 | } | |
40 | return __syscall_ret(r); | |
320054e8 | 41 | } |