fix aliasing-based undefined behavior in mbsrtowcs
[musl] / src / network / getsockopt.c
index a9e0a72..e871d62 100644 (file)
@@ -1,7 +1,32 @@
 #include <sys/socket.h>
+#include <sys/time.h>
+#include <errno.h>
 #include "syscall.h"
 
-int getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlen)
+int getsockopt(int fd, int level, int optname, void *restrict optval, socklen_t *restrict optlen)
 {
-       return socketcall(getsockopt, fd, level, optname, optval, optlen, 0);
+       long tv32[2];
+       struct timeval *tv;
+
+       int r = __socketcall(getsockopt, fd, level, optname, optval, optlen, 0);
+
+       if (r==-ENOPROTOOPT) switch (level) {
+       case SOL_SOCKET:
+               switch (optname) {
+               case SO_RCVTIMEO:
+               case SO_SNDTIMEO:
+                       if (SO_RCVTIMEO == SO_RCVTIMEO_OLD) break;
+                       if (*optlen < sizeof *tv) return __syscall_ret(-EINVAL);
+                       if (optname==SO_RCVTIMEO) optname=SO_RCVTIMEO_OLD;
+                       if (optname==SO_SNDTIMEO) optname=SO_SNDTIMEO_OLD;
+                       r = __socketcall(getsockopt, fd, level, optname,
+                               tv32, (socklen_t[]){sizeof tv32}, 0);
+                       if (r<0) break;
+                       tv = optval;
+                       tv->tv_sec = tv32[0];
+                       tv->tv_usec = tv32[1];
+                       *optlen = sizeof *tv;
+               }
+       }
+       return __syscall_ret(r);
 }