[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH] linux-user/syscall.c: Add SO_RCVTIMEO and SO_SN
From: |
Laurent Vivier |
Subject: |
Re: [Qemu-devel] [PATCH] linux-user/syscall.c: Add SO_RCVTIMEO and SO_SNDTIMEO for getsockopt |
Date: |
Fri, 8 Jan 2016 09:25:20 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.4.0 |
Le 08/01/2016 02:59, address@hidden a écrit :
> From: Chen Gang <address@hidden>
>
> Just implement them according to the other features implementations.
>
> Signed-off-by: Chen Gang <address@hidden>
> ---
> linux-user/syscall.c | 25 +++++++++++++++++++++++--
> 1 file changed, 23 insertions(+), 2 deletions(-)
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 12a6cd2..f27148a 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -1685,6 +1685,7 @@ static abi_long do_getsockopt(int sockfd, int level,
> int optname,
> abi_long ret;
> int len, val;
> socklen_t lv;
> + struct timeval tv;
>
> switch(level) {
> case TARGET_SOL_SOCKET:
> @@ -1692,10 +1693,30 @@ static abi_long do_getsockopt(int sockfd, int level,
> int optname,
> 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_PEERNAME:
> goto unimplemented;
> +
useless blank line
> + case TARGET_SO_RCVTIMEO:
> + optname = SO_RCVTIMEO;
> + goto time_case;
> + case TARGET_SO_SNDTIMEO:
> + optname = SO_SNDTIMEO;
> + time_case:
Something like in "int_case", I think optlen is a pointer, not the length:
if (get_user_u32(len, optlen))
return -TARGET_EFAULT;
if (len < 0)
return -TARGET_EINVAL;
> + if (optlen < sizeof(struct target_timeval)) {
> + return -TARGET_EINVAL;
> + }
You don't have to check the len (kernel doesn't), EINVAL is not listed
in the getsockopt() error cases, it should be an EFAULT, and this will
be managed by copy_to_user_timeval().
> + lv = sizeof(tv);
> + ret = get_errno(getsockopt(sockfd, level, optname, &tv, &lv));
> + if (ret < 0) {
> + return ret;
> + }
if (len > lv)
len = lv;
> + if (copy_to_user_timeval(optval_addr, &tv)) {
> + return -TARGET_EFAULT;
> + }
> + if (put_user_u32(sizeof(struct target_timeval), optlen)) {
> + return -TARGET_EFAULT;
> + }
if (put_user_u32(len, optlen))
return -TARGET_EFAULT;
> + break;
> case TARGET_SO_PEERCRED: {
> struct ucred cr;
> socklen_t crlen;
>
Laurent