Complete bsd-socket.h with socketpair, sendto, recvfrom, socket, and shutdown system call shims.
Signed-off-by: Stacey Son <[email protected]> Signed-off-by: Kyle Evans <[email protected]> Signed-off-by: Warner Losh <[email protected]> Assisted-by: Claude Opus 4.6 (1M context) --- bsd-user/bsd-socket.h | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/bsd-user/bsd-socket.h b/bsd-user/bsd-socket.h index 121d3e2a05..578cc3959d 100644 --- a/bsd-user/bsd-socket.h +++ b/bsd-user/bsd-socket.h @@ -157,4 +157,118 @@ static inline abi_long do_bsd_getsockname(int fd, abi_ulong target_addr, return ret; } +/* socketpair(2) */ +static inline abi_long do_bsd_socketpair(int domain, int type, int protocol, + abi_ulong target_tab_addr) +{ + int tab[2]; + abi_long ret; + + if (!access_ok(VERIFY_WRITE, target_tab_addr, sizeof(tab[0]) * 2)) { + return -TARGET_EFAULT; + } + ret = get_errno(socketpair(domain, type, protocol, tab)); + if (!is_error(ret)) { + if (put_user_s32(tab[0], target_tab_addr) || + put_user_s32(tab[1], target_tab_addr + sizeof(tab[0]))) { + ret = -TARGET_EFAULT; + } + } + return ret; +} + +/* sendto(2) */ +static inline abi_long do_bsd_sendto(int fd, abi_ulong msg, size_t len, + int flags, abi_ulong target_addr, + socklen_t addrlen) +{ + struct sockaddr *saddr; + void *host_msg; + abi_long ret; + + if ((int)addrlen < 0) { + return -TARGET_EINVAL; + } + if (len != 0) { + host_msg = lock_user(VERIFY_READ, msg, len, 1); + if (!host_msg) { + return -TARGET_EFAULT; + } + } else { + host_msg = NULL; + } + if (target_addr) { + saddr = alloca(addrlen); + ret = target_to_host_sockaddr(saddr, target_addr, addrlen); + if (is_error(ret)) { + unlock_user(host_msg, msg, 0); + return ret; + } + ret = get_errno(safe_sendto(fd, host_msg, len, flags, saddr, addrlen)); + } else { + ret = get_errno(send(fd, host_msg, len, flags)); + } + unlock_user(host_msg, msg, 0); + return ret; +} + +/* recvfrom(2) */ +static inline abi_long do_bsd_recvfrom(int fd, abi_ulong msg, size_t len, + int flags, abi_ulong target_addr, + abi_ulong target_addrlen) +{ + socklen_t addrlen; + struct sockaddr *saddr; + void *host_msg; + abi_long ret; + + host_msg = lock_user(VERIFY_WRITE, msg, len, 0); + if (!host_msg) { + return -TARGET_EFAULT; + } + if (target_addr) { + if (get_user_u32(addrlen, target_addrlen)) { + ret = -TARGET_EFAULT; + goto fail; + } + if ((int)addrlen < 0) { + ret = -TARGET_EINVAL; + goto fail; + } + saddr = alloca(addrlen); + ret = get_errno(safe_recvfrom(fd, host_msg, len, flags, saddr, + &addrlen)); + } else { + saddr = NULL; /* To keep compiler quiet. */ + ret = get_errno(recv(fd, host_msg, len, flags)); + } + if (!is_error(ret)) { + if (target_addr) { + host_to_target_sockaddr(target_addr, saddr, addrlen); + if (put_user_u32(addrlen, target_addrlen)) { + ret = -TARGET_EFAULT; + goto fail; + } + } + unlock_user(host_msg, msg, len); + } else { +fail: + unlock_user(host_msg, msg, 0); + } + return ret; +} + +/* socket(2) */ +static inline abi_long do_bsd_socket(abi_long domain, abi_long type, + abi_long protocol) +{ + return get_errno(socket(domain, type, protocol)); +} + +/* shutdown(2) */ +static inline abi_long do_bsd_shutdown(abi_long s, abi_long how) +{ + return get_errno(shutdown(s, how)); +} + #endif /* BSD_SOCKET_H */ -- 2.52.0
