qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 01/16] linux-user: translate the result of getso


From: Riku Voipio
Subject: Re: [Qemu-devel] [PATCH 01/16] linux-user: translate the result of getsockopt SO_TYPE
Date: Sat, 21 Jun 2014 12:39:12 +0300
User-agent: Mutt/1.5.21 (2010-09-15)

On Sun, Jun 15, 2014 at 05:18:18PM +0100, Paul Burton wrote:
> QEMU previously passed the result of the host syscall directly to the
> target program. This is a problem if the host & target have different
> representations of socket types, as is the case when running a MIPS
> target program on an x86 host. Introduce a host_to_target_sock_type
> helper function mirroring the existing target_to_host_sock_type, and
> call it to translate the value provided by getsockopt when called for
> the SO_TYPE option.
> 
> Signed-off-by: Paul Burton <address@hidden>
> ---
>  linux-user/syscall.c | 33 +++++++++++++++++++++++++++++++++
>  1 file changed, 33 insertions(+)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 6efeeff..3921cff 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -592,6 +592,35 @@ char *target_strerror(int err)
>      return strerror(target_to_host_errno(err));
>  }
>  
> +static inline int host_to_target_sock_type(int host_type)
> +{
> +    int target_type;
> +
> +    switch (host_type & 0xf /* SOCK_TYPE_MASK */) {
> +    case SOCK_DGRAM:
> +        target_type = TARGET_SOCK_DGRAM;
> +        break;
> +    case SOCK_STREAM:
> +        target_type = TARGET_SOCK_STREAM;
> +        break;
> +    default:
> +        target_type = host_type & 0xf /* SOCK_TYPE_MASK */;
> +        break;
> +    }
> +
> +#if defined(SOCK_CLOEXEC)
> +    if (host_type & SOCK_CLOEXEC)
> +        target_type |= TARGET_SOCK_CLOEXEC;
> +#endif
> +
> +#if defined(SOCK_NONBLOCK)
> +    if (host_type & SOCK_NONBLOCK)
> +        target_type |= TARGET_SOCK_NONBLOCK;
> +#endif
> +
> +    return target_type;
> +}
> +
>  static abi_ulong target_brk;
>  static abi_ulong target_original_brk;
>  static abi_ulong brk_page;
> @@ -1526,6 +1555,7 @@ static abi_long do_getsockopt(int sockfd, int level, 
> int optname,
>      abi_long ret;
>      int len, val;
>      socklen_t lv;
> +    int (*translate_result)(int val) = NULL;
>  
>      switch(level) {
>      case TARGET_SOL_SOCKET:
> @@ -1578,6 +1608,7 @@ static abi_long do_getsockopt(int sockfd, int level, 
> int optname,
>              optname = SO_REUSEADDR;
>              goto int_case;
>          case TARGET_SO_TYPE:
> +            translate_result = host_to_target_sock_type;
>              optname = SO_TYPE;
>              goto int_case;
>          case TARGET_SO_ERROR:
> @@ -1636,6 +1667,8 @@ static abi_long do_getsockopt(int sockfd, int level, 
> int optname,
>          ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv));
>          if (ret < 0)
>              return ret;
> +        if (translate_result)
> +            val = translate_result(val);

perhaps instead:

        if (optname == SO_TYPE)
            val = host_to_target_sock_type(val);

Then we avoid the need of function pointer. 

>          if (len > lv)
>              len = lv;
>          if (len == 4) {
> -- 
> 2.0.0
> 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]