linux-user: translate the result of getsockopt SO_TYPE
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 <paul@archlinuxmips.org> Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
This commit is contained in:
parent
76b9424550
commit
8289d11281
@ -592,6 +592,37 @@ 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;
|
||||
@ -1636,6 +1667,9 @@ 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 (optname == SO_TYPE) {
|
||||
val = host_to_target_sock_type(val);
|
||||
}
|
||||
if (len > lv)
|
||||
len = lv;
|
||||
if (len == 4) {
|
||||
|
Loading…
Reference in New Issue
Block a user