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>
This commit is contained in:
Jamie Lentin 2010-11-26 15:04:08 +02:00 committed by Riku Voipio
parent bee7000807
commit f3b974cd3b
1 changed files with 61 additions and 10 deletions

View File

@ -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;