Signed-off-by: Andreas Schwab <sch...@suse.de> --- linux-user/syscall.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c index d113a65831..ba5775a94e 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2171,10 +2171,42 @@ static abi_long do_getsockopt(int sockfd, int level, int optname, level = SOL_SOCKET; switch (optname) { /* These don't just return a single integer */ - case TARGET_SO_RCVTIMEO: - case TARGET_SO_SNDTIMEO: case TARGET_SO_PEERNAME: goto unimplemented; + case TARGET_SO_RCVTIMEO: { + struct timeval tv; + socklen_t tvlen; + + optname = SO_RCVTIMEO; + +get_timeout: + if (get_user_u32(len, optlen)) { + return -TARGET_EFAULT; + } + if (len < 0) { + return -TARGET_EINVAL; + } + + tvlen = sizeof(tv); + ret = get_errno(getsockopt(sockfd, level, optname, + &tv, &tvlen)); + if (ret < 0) { + return ret; + } + if (len > sizeof(struct target_timeval)) { + len = sizeof(struct target_timeval); + } + if (copy_to_user_timeval(optval_addr, &tv)) { + return -TARGET_EFAULT; + } + if (put_user_u32(len, optlen)) { + return -TARGET_EFAULT; + } + break; + } + case TARGET_SO_SNDTIMEO: + optname = SO_SNDTIMEO; + goto get_timeout; case TARGET_SO_PEERCRED: { struct ucred cr; socklen_t crlen; -- 2.21.0 -- Andreas Schwab, SUSE Labs, sch...@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different."