Patchwork qemu-user: Translate getsockopt level option

login
register
mail settings
Submitter Jamie Lentin
Date Nov. 17, 2010, 12:30 p.m.
Message ID <alpine.DEB.2.00.1011171227370.27850@bunsen.wrottesley.wormnet.eu>
Download mbox | patch
Permalink /patch/71558/
State New
Headers show

Comments

Jamie Lentin - Nov. 17, 2010, 12:30 p.m.
In 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

Signed-off-by: Jamie Lentin <jm@lentin.co.uk>
---
Peter Maydell - Dec. 1, 2010, 11:43 a.m.
On 17 November 2010 12:30, Jamie Lentin <jm@lentin.co.uk> wrote:
> In 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.

I agree that this is necessary (at least for MIPS; I think all
the other architectures happen to have the same values for the
constants so the bug doesn't cause problems.

> diff -uprN a/linux-user/syscall.c b/linux-user/syscall.c
> --- a/linux-user/syscall.c      2010-05-04 16:27:48.000000000 +0100
> +++ b/linux-user/syscall.c      2010-07-29 21:47:12.000000000 +0100
> @@ -1383,6 +1383,57 @@ static abi_long do_getsockopt(int sockfd
>        case TARGET_SO_PEERNAME:
>            /* These don't just return a single integer */
>            goto unimplemented;
> +            /* Options with 'int' argument.  */
> +        case TARGET_SO_DEBUG:
> +            optname = SO_DEBUG;
> +            goto int_case;

[etc]

Wouldn't it be better to have a helper function for the conversion
rather than duplicating this set of cases in getsockopt() and
setsockopt() ?  (cf target_to_host_fcntl_cmd).

-- PMM

Patch

diff -uprN a/linux-user/syscall.c b/linux-user/syscall.c
--- a/linux-user/syscall.c	2010-05-04 16:27:48.000000000 +0100
+++ b/linux-user/syscall.c	2010-07-29 21:47:12.000000000 +0100
@@ -1383,6 +1383,57 @@  static abi_long do_getsockopt(int sockfd
  	case TARGET_SO_PEERNAME:
  	    /* These don't just return a single integer */
  	    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;
          }