diff mbox

add target to host SO_* translation to getsocketopt

Message ID 1213fd545e8fde1612c17e98533043f5.squirrel@alpha
State Superseded
Headers show

Commit Message

Gabriele Gorla Sept. 2, 2009, 3:58 a.m. UTC
getsockopt will fail when the define for the socket options differ between
target and host.

This patch extracts the trnalsation code from setsockopt into a new
function and uses the function in both setsockopt and getsockopt.

Signed-off-by: Gabriele Gorla <gorlik@penguintown.net>
---
diff mbox

Patch

diff -r -U 5 qemu-0.10.6_orig/linux-user/syscall.c
qemu-0.10.6/linux-user/syscall.c
--- qemu-0.10.6_orig/linux-user/syscall.c	2009-07-16 17:56:24 -0700
+++ qemu-0.10.6/linux-user/syscall.c	2009-09-01 20:44:37 -0700
@@ -831,10 +831,77 @@ 
  the_end:
     target_msgh->msg_controllen = tswapl(space);
     return 0;
 }

+static int so_target_to_host(int optname)
+{
+    switch (optname) {
+    /* Options with 'int' argument.  */
+    case TARGET_SO_DEBUG:
+	optname = SO_DEBUG;
+	break;
+    case TARGET_SO_REUSEADDR:
+	optname = SO_REUSEADDR;
+	break;
+    case TARGET_SO_TYPE:
+	optname = SO_TYPE;
+	break;
+    case TARGET_SO_ERROR:
+	optname = SO_ERROR;
+	break;
+    case TARGET_SO_DONTROUTE:
+	optname = SO_DONTROUTE;
+	break;
+    case TARGET_SO_BROADCAST:
+	optname = SO_BROADCAST;
+	break;
+    case TARGET_SO_SNDBUF:
+	optname = SO_SNDBUF;
+	break;
+    case TARGET_SO_RCVBUF:
+	optname = SO_RCVBUF;
+	break;
+    case TARGET_SO_KEEPALIVE:
+	optname = SO_KEEPALIVE;
+	break;
+    case TARGET_SO_OOBINLINE:
+	optname = SO_OOBINLINE;
+	break;
+    case TARGET_SO_NO_CHECK:
+	optname = SO_NO_CHECK;
+	break;
+    case TARGET_SO_PRIORITY:
+	optname = SO_PRIORITY;
+	break;
+#ifdef SO_BSDCOMPAT
+    case TARGET_SO_BSDCOMPAT:
+	optname = SO_BSDCOMPAT;
+	break;
+#endif
+    case TARGET_SO_PASSCRED:
+	optname = SO_PASSCRED;
+	break;
+    case TARGET_SO_TIMESTAMP:
+	optname = SO_TIMESTAMP;
+	break;
+    case TARGET_SO_RCVLOWAT:
+	optname = SO_RCVLOWAT;
+	break;
+    case TARGET_SO_RCVTIMEO:
+	optname = SO_RCVTIMEO;
+	break;
+    case TARGET_SO_SNDTIMEO:
+	optname = SO_SNDTIMEO;
+	break;
+        break;
+    default:
+        optname=0;
+    }
+    return optname;
+}
+
 /* do_setsockopt() Must return target values and target errnos. */
 static abi_long do_setsockopt(int sockfd, int level, int optname,
                               abi_ulong optval_addr, socklen_t optlen)
 {
     abi_long ret;
@@ -880,72 +947,12 @@ 
         default:
             goto unimplemented;
         }
         break;
     case TARGET_SOL_SOCKET:
-        switch (optname) {
-            /* Options with 'int' argument.  */
-        case TARGET_SO_DEBUG:
-		optname = SO_DEBUG;
-		break;
-        case TARGET_SO_REUSEADDR:
-		optname = SO_REUSEADDR;
-		break;
-        case TARGET_SO_TYPE:
-		optname = SO_TYPE;
-		break;
-        case TARGET_SO_ERROR:
-		optname = SO_ERROR;
-		break;
-        case TARGET_SO_DONTROUTE:
-		optname = SO_DONTROUTE;
-		break;
-        case TARGET_SO_BROADCAST:
-		optname = SO_BROADCAST;
-		break;
-        case TARGET_SO_SNDBUF:
-		optname = SO_SNDBUF;
-		break;
-        case TARGET_SO_RCVBUF:
-		optname = SO_RCVBUF;
-		break;
-        case TARGET_SO_KEEPALIVE:
-		optname = SO_KEEPALIVE;
-		break;
-        case TARGET_SO_OOBINLINE:
-		optname = SO_OOBINLINE;
-		break;
-        case TARGET_SO_NO_CHECK:
-		optname = SO_NO_CHECK;
-		break;
-        case TARGET_SO_PRIORITY:
-		optname = SO_PRIORITY;
-		break;
-#ifdef SO_BSDCOMPAT
-        case TARGET_SO_BSDCOMPAT:
-		optname = SO_BSDCOMPAT;
-		break;
-#endif
-        case TARGET_SO_PASSCRED:
-		optname = SO_PASSCRED;
-		break;
-        case TARGET_SO_TIMESTAMP:
-		optname = SO_TIMESTAMP;
-		break;
-        case TARGET_SO_RCVLOWAT:
-		optname = SO_RCVLOWAT;
-		break;
-        case TARGET_SO_RCVTIMEO:
-		optname = SO_RCVTIMEO;
-		break;
-        case TARGET_SO_SNDTIMEO:
-		optname = SO_SNDTIMEO;
-		break;
-            break;
-        default:
-            goto unimplemented;
-        }
+        optname=so_target_to_host(optname);
+        if(optname==0) goto unimplemented;
 	if (optlen < sizeof(uint32_t))
             return -TARGET_EINVAL;

 	if (get_user_u32(val, optval_addr))
             return -TARGET_EFAULT;
@@ -983,10 +990,12 @@ 
         }
         break;
     case SOL_TCP:
         /* TCP options all take an 'int' value.  */
     int_case:
+        optname=so_target_to_host(optname);
+        if(optname==0) goto unimplemented;
         if (get_user_u32(len, optlen))
             return -TARGET_EFAULT;
         if (len < 0)
             return -TARGET_EINVAL;
         lv = sizeof(int);