diff options
author | Petar Jovanovic <petar.jovanovic@imgtec.com> | 2013-07-01 02:44:14 +0200 |
---|---|---|
committer | Riku Voipio <riku.voipio@linaro.org> | 2013-07-05 15:45:40 +0300 |
commit | f651e6ae55b047a8ac4b6b5891fe69ba4c66c57c (patch) | |
tree | 6a5d726a907176a6fcf7725becbe72ea6f1d4336 /linux-user/syscall.c | |
parent | 023b0ae33be6ce2e60d75d2b54a3d2cea6b6020e (diff) |
linux-user: improve target_to_host_sock_type conversion
Previous implementation has failed to take into account different value of
SOCK_NONBLOCK on target and host, and existence of SOCK_CLOEXEC.
The same conversion has to be applied both for do_socket and do_socketpair,
so the code has been isolated in a static inline function.
enum sock_type in linux-user/socket.h has been extended to include
TARGET_SOCK_CLOEXEC and TARGET_SOCK_NONBLOCK, similar to definition in libc.
The patch also includes necessary code style changes (tab to spaces) in the
header file since most of the file has been touched by this change.
Signed-off-by: Petar Jovanovic <petar.jovanovic@imgtec.com>
Message-id: 1372639454-7560-1-git-send-email-petar.jovanovic@rt-rk.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'linux-user/syscall.c')
-rw-r--r-- | linux-user/syscall.c | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/linux-user/syscall.c b/linux-user/syscall.c index d74836ad9c..a6a7828cc3 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -1705,31 +1705,36 @@ static void unlock_iovec(struct iovec *vec, abi_ulong target_addr, free(vec); } -/* do_socket() Must return target values and target errnos. */ -static abi_long do_socket(int domain, int type, int protocol) +static inline void target_to_host_sock_type(int *type) { -#if defined(TARGET_MIPS) - switch(type) { + int host_type = 0; + int target_type = *type; + + switch (target_type & TARGET_SOCK_TYPE_MASK) { case TARGET_SOCK_DGRAM: - type = SOCK_DGRAM; + host_type = SOCK_DGRAM; break; case TARGET_SOCK_STREAM: - type = SOCK_STREAM; - break; - case TARGET_SOCK_RAW: - type = SOCK_RAW; + host_type = SOCK_STREAM; break; - case TARGET_SOCK_RDM: - type = SOCK_RDM; - break; - case TARGET_SOCK_SEQPACKET: - type = SOCK_SEQPACKET; - break; - case TARGET_SOCK_PACKET: - type = SOCK_PACKET; + default: + host_type = target_type & TARGET_SOCK_TYPE_MASK; break; } -#endif + if (target_type & TARGET_SOCK_CLOEXEC) { + host_type |= SOCK_CLOEXEC; + } + if (target_type & TARGET_SOCK_NONBLOCK) { + host_type |= SOCK_NONBLOCK; + } + *type = host_type; +} + +/* do_socket() Must return target values and target errnos. */ +static abi_long do_socket(int domain, int type, int protocol) +{ + target_to_host_sock_type(&type); + if (domain == PF_NETLINK) return -EAFNOSUPPORT; /* do not NETLINK socket connections possible */ return get_errno(socket(domain, type, protocol)); @@ -1962,6 +1967,8 @@ static abi_long do_socketpair(int domain, int type, int protocol, int tab[2]; abi_long ret; + target_to_host_sock_type(&type); + ret = get_errno(socketpair(domain, type, protocol, tab)); if (!is_error(ret)) { if (put_user_s32(tab[0], target_tab_addr) |