[PATCH v4 18/40] bsd-user: Add FreeBSD socket system calls
Warner Losh <[email protected]>
| Newsgroups | gmane.comp.emulators.qemu |
|---|---|
| Message-ID | <[email protected]> |
Complete os-socket.h with setfib, bindat, connectat, and accept4. Signed-off-by: Stacey Son <[email protected]> Assisted-by: Claude Opus 4.6 (1M context) Reviewed-by: Pierrick Bouvier <[email protected]> Acked-by: Richard Henderson <[email protected]> Signed-off-by: Warner Losh <[email protected]> --- bsd-user/freebsd/os-socket.h | 83 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/bsd-user/freebsd/os-socket.h b/bsd-user/freebsd/os-socket.h index 126e49b282..b0f2498ff7 100644 --- a/bsd-user/freebsd/os-socket.h +++ b/bsd-user/freebsd/os-socket.h @@ -336,5 +336,88 @@ done: return ret; } +/* setfib(2) */ +static inline abi_long do_freebsd_setfib(abi_long fib) +{ + + return get_errno(setfib(fib)); +} + +/* bindat(2) */ +static inline abi_long do_freebsd_bindat(int fd, int sockfd, + abi_ulong target_addr, socklen_t addrlen) +{ + abi_long ret; + void *addr; + + if ((int)addrlen < 0) { + return -TARGET_EINVAL; + } + + addr = alloca(addrlen + 1); + ret = target_to_host_sockaddr(addr, target_addr, addrlen); + if (is_error(ret)) { + return ret; + } + + return get_errno(bindat(fd, sockfd, addr, addrlen)); +} + +/* connectat(2) */ +static inline abi_long do_freebsd_connectat(int fd, int sockfd, + abi_ulong target_addr, socklen_t addrlen) +{ + abi_long ret; + void *addr; + + if ((int)addrlen < 0) { + return -TARGET_EINVAL; + } + addr = alloca(addrlen + 1); + + ret = target_to_host_sockaddr(addr, target_addr, addrlen); + + if (is_error(ret)) { + return ret; + } + + return get_errno(connectat(fd, sockfd, addr, addrlen)); +} + +/* accept4(2) */ +static inline abi_long do_freebsd_accept4(int fd, abi_ulong target_addr, + abi_ulong target_addrlen_addr, int flags) +{ + socklen_t addrlen; + void *addr; + abi_long ret; + + if (target_addr == 0) { + return get_errno(accept(fd, NULL, NULL)); + } + /* return EINVAL if addrlen pointer is invalid */ + if (get_user_u32(addrlen, target_addrlen_addr)) { + return -TARGET_EINVAL; + } + if ((int)addrlen < 0) { + return -TARGET_EINVAL; + } + if (!access_ok(VERIFY_WRITE, target_addr, addrlen)) { + return -TARGET_EINVAL; + } + addr = alloca(addrlen); + + ret = get_errno(accept4(fd, addr, &addrlen, flags)); + if (!is_error(ret)) { + if (is_error(host_to_target_sockaddr(target_addr, addr, addrlen))) { + close(ret); + ret = -TARGET_EFAULT; + } else if (put_user_u32(addrlen, target_addrlen_addr)) { + close(ret); + ret = -TARGET_EFAULT; + } + } + return ret; +} #endif /* BSD_USER_FREEBSD_OS_SOCKET_H */ -- 2.55.0