From f3b974cd3bb624cc7a3004db902b59d599ff016a Mon Sep 17 00:00:00 2001 From: Jamie Lentin Date: Fri, 26 Nov 2010 15:04:08 +0200 Subject: 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 Signed-off-by: Riku Voipio --- linux-user/syscall.c | 71 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 61 insertions(+), 10 deletions(-) (limited to 'linux-user/syscall.c') diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 5761106cec..070241bb8a 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; -- cgit v1.2.1