]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
linux-user: implement getsockopt SO_RCVTIMEO and SO_SNDTIMEO
authorAndreas Schwab <schwab@suse.de>
Mon, 13 May 2019 09:06:26 +0000 (11:06 +0200)
committerLaurent Vivier <laurent@vivier.eu>
Wed, 19 Feb 2020 10:17:40 +0000 (11:17 +0100)
Signed-off-by: Andreas Schwab <schwab@suse.de>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Message-Id: <mvmlfzaoh9p.fsf@suse.de>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
linux-user/syscall.c

index 7aaa9d96397c8ffa5c8bd5bb7f4df745e5d3983b..9fa722f2388db2b1cc5fe76bdc1680e6b15f4275 100644 (file)
@@ -2310,10 +2310,42 @@ static abi_long do_getsockopt(int sockfd, int level, int optname,
         level = SOL_SOCKET;
         switch (optname) {
         /* These don't just return a single integer */
-        case TARGET_SO_RCVTIMEO:
-        case TARGET_SO_SNDTIMEO:
         case TARGET_SO_PEERNAME:
             goto unimplemented;
+        case TARGET_SO_RCVTIMEO: {
+            struct timeval tv;
+            socklen_t tvlen;
+
+            optname = SO_RCVTIMEO;
+
+get_timeout:
+            if (get_user_u32(len, optlen)) {
+                return -TARGET_EFAULT;
+            }
+            if (len < 0) {
+                return -TARGET_EINVAL;
+            }
+
+            tvlen = sizeof(tv);
+            ret = get_errno(getsockopt(sockfd, level, optname,
+                                       &tv, &tvlen));
+            if (ret < 0) {
+                return ret;
+            }
+            if (len > sizeof(struct target_timeval)) {
+                len = sizeof(struct target_timeval);
+            }
+            if (copy_to_user_timeval(optval_addr, &tv)) {
+                return -TARGET_EFAULT;
+            }
+            if (put_user_u32(len, optlen)) {
+                return -TARGET_EFAULT;
+            }
+            break;
+        }
+        case TARGET_SO_SNDTIMEO:
+            optname = SO_SNDTIMEO;
+            goto get_timeout;
         case TARGET_SO_PEERCRED: {
             struct ucred cr;
             socklen_t crlen;