Patchwork [05/16] linux-user: Translate getsockopt level option

login
register
mail settings
Submitter Riku@afflict.kos.to, Voipio@afflict.kos.to
Date Dec. 3, 2010, 1:36 p.m.
Message ID <f3b974cd3bb624cc7a3004db902b59d599ff016a.1291382447.git.riku.voipio@nokia.com>
Download mbox | patch
Permalink /patch/74144/
State New
Headers show

Comments

From: Jamie Lentin <jm@lentin.co.uk>

n setsockopt, the socket level options are translated to the hosts'
architecture before the real syscall is called, e.g.
TARGET_SO_TYPE -> SO_TYPE. This patch does the same with getsockopt.

Tested on a x86 host emulating MIPS.  Without it:-

$ grep getsockopt host.strace
31311 getsockopt(3, SOL_SOCKET, 0x1007 /* SO_??? */, 0xbff17208,
0xbff17204) = -1 ENOPROTOOPT (Protocol not available)

With:-

$ grep getsockopt host.strace
25706 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0

Whitespace cleanup: Riku Voipio

Signed-off-by: Jamie Lentin <jm@lentin.co.uk>
Signed-off-by: Riku Voipio <riku.voipio@iki.fi>
---
 linux-user/syscall.c |   71 +++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 61 insertions(+), 10 deletions(-)

Patch

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 5761106..070241b 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -1374,15 +1374,66 @@  static abi_long do_getsockopt(int sockfd, int level, int optname,
 
     switch(level) {
     case TARGET_SOL_SOCKET:
-    	level = SOL_SOCKET;
-	switch (optname) {
-	case TARGET_SO_LINGER:
-	case TARGET_SO_RCVTIMEO:
-	case TARGET_SO_SNDTIMEO:
-	case TARGET_SO_PEERCRED:
-	case TARGET_SO_PEERNAME:
-	    /* These don't just return a single integer */
-	    goto unimplemented;
+        level = SOL_SOCKET;
+        switch (optname) {
+        /* These don't just return a single integer */
+        case TARGET_SO_LINGER:
+        case TARGET_SO_RCVTIMEO:
+        case TARGET_SO_SNDTIMEO:
+        case TARGET_SO_PEERCRED:
+        case TARGET_SO_PEERNAME:
+            goto unimplemented;
+        /* Options with 'int' argument.  */
+        case TARGET_SO_DEBUG:
+            optname = SO_DEBUG;
+            goto int_case;
+        case TARGET_SO_REUSEADDR:
+            optname = SO_REUSEADDR;
+            goto int_case;
+        case TARGET_SO_TYPE:
+            optname = SO_TYPE;
+            goto int_case;
+        case TARGET_SO_ERROR:
+            optname = SO_ERROR;
+            goto int_case;
+        case TARGET_SO_DONTROUTE:
+            optname = SO_DONTROUTE;
+            goto int_case;
+        case TARGET_SO_BROADCAST:
+            optname = SO_BROADCAST;
+            goto int_case;
+        case TARGET_SO_SNDBUF:
+            optname = SO_SNDBUF;
+            goto int_case;
+        case TARGET_SO_RCVBUF:
+            optname = SO_RCVBUF;
+            goto int_case;
+        case TARGET_SO_KEEPALIVE:
+            optname = SO_KEEPALIVE;
+            goto int_case;
+        case TARGET_SO_OOBINLINE:
+            optname = SO_OOBINLINE;
+            goto int_case;
+        case TARGET_SO_NO_CHECK:
+            optname = SO_NO_CHECK;
+            goto int_case;
+        case TARGET_SO_PRIORITY:
+            optname = SO_PRIORITY;
+            goto int_case;
+#ifdef SO_BSDCOMPAT
+        case TARGET_SO_BSDCOMPAT:
+            optname = SO_BSDCOMPAT;
+            goto int_case;
+#endif
+        case TARGET_SO_PASSCRED:
+            optname = SO_PASSCRED;
+            goto int_case;
+        case TARGET_SO_TIMESTAMP:
+            optname = SO_TIMESTAMP;
+            goto int_case;
+        case TARGET_SO_RCVLOWAT:
+            optname = SO_RCVLOWAT;
+            goto int_case;
         default:
             goto int_case;
         }
@@ -1406,7 +1457,7 @@  static abi_long do_getsockopt(int sockfd, int level, int optname,
         } else {
             if (put_user_u8(val, optval_addr))
                 return -TARGET_EFAULT;
-	}
+        }
         if (put_user_u32(len, optlen))
             return -TARGET_EFAULT;
         break;