diff options
author | Jamie Lentin <jm@lentin.co.uk> | 2010-11-26 15:04:08 +0200 |
---|---|---|
committer | Riku Voipio <riku.voipio@nokia.com> | 2010-12-03 15:09:39 +0200 |
commit | f3b974cd3bb624cc7a3004db902b59d599ff016a (patch) | |
tree | a22dbe7945ce6d4aa5c6ad22c3d921c78610634b /linux-user | |
parent | bee70008074570ef2c368aec80918c2494065247 (diff) | |
download | qemu-f3b974cd3bb624cc7a3004db902b59d599ff016a.zip qemu-f3b974cd3bb624cc7a3004db902b59d599ff016a.tar.gz qemu-f3b974cd3bb624cc7a3004db902b59d599ff016a.tar.bz2 |
linux-user: Translate getsockopt level option
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>
Diffstat (limited to 'linux-user')
-rw-r--r-- | linux-user/syscall.c | 71 |
1 files changed, 61 insertions, 10 deletions
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; |