From 289cf8d7ef0e8289471b8cec038f2c10e9247467 Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Sat, 25 Dec 2021 12:52:19 +0000 Subject: [PATCH] LibCore: Add ErrorOr wrappers to socket syscalls These are all pretty simple so I thought I would add them all in one go: - socket() - bind() - listen() - accept() - accept4() - connect() - shutdown() - send() - sendmsg() - sendto() - recv() - recvmsg() - recvfrom() - getsockopt() - setsockopt() - getsockname() - getpeername() - socketpair() --- Userland/Libraries/LibCore/System.cpp | 140 +++++++++++++++++++++++++- Userland/Libraries/LibCore/System.h | 26 +++++ 2 files changed, 164 insertions(+), 2 deletions(-) diff --git a/Userland/Libraries/LibCore/System.cpp b/Userland/Libraries/LibCore/System.cpp index 5cbae05735..19ad7c9d26 100644 --- a/Userland/Libraries/LibCore/System.cpp +++ b/Userland/Libraries/LibCore/System.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2021, Andreas Kling * Copyright (c) 2021, Kenneth Myhra + * Copyright (c) 2021, Sam Atkins * * SPDX-License-Identifier: BSD-2-Clause */ @@ -8,12 +9,10 @@ #include #include #include -#include #include #include #include #include -#include #include #include @@ -115,6 +114,16 @@ ErrorOr ptrace(int request, pid_t tid, void* address, void* data) } #endif +#ifndef AK_OS_MACOS +ErrorOr accept4(int sockfd, sockaddr* address, socklen_t* address_length, int flags) +{ + auto fd = ::accept4(sockfd, address, address_length, flags); + if (fd < 0) + return Error::from_syscall("accept4"sv, -errno); + return fd; +} +#endif + ErrorOr sigaction(int signal, struct sigaction const* action, struct sigaction* old_action) { if (::sigaction(signal, action, old_action) < 0) @@ -573,4 +582,131 @@ ErrorOr utime(StringView path, Optional maybe_buf) #endif } +ErrorOr socket(int domain, int type, int protocol) +{ + auto fd = ::socket(domain, type, protocol); + if (fd < 0) + return Error::from_syscall("socket"sv, -errno); + return fd; +} + +ErrorOr bind(int sockfd, struct sockaddr const* address, socklen_t address_length) +{ + if (::bind(sockfd, address, address_length) < 0) + return Error::from_syscall("bind"sv, -errno); + return {}; +} + +ErrorOr listen(int sockfd, int backlog) +{ + if (::listen(sockfd, backlog) < 0) + return Error::from_syscall("listen"sv, -errno); + return {}; +} + +ErrorOr accept(int sockfd, struct sockaddr* address, socklen_t* address_length) +{ + auto fd = ::accept(sockfd, address, address_length); + if (fd < 0) + return Error::from_syscall("accept"sv, -errno); + return fd; +} + +ErrorOr connect(int sockfd, struct sockaddr const* address, socklen_t address_length) +{ + if (::connect(sockfd, address, address_length) < 0) + return Error::from_syscall("connect"sv, -errno); + return {}; +} + +ErrorOr shutdown(int sockfd, int how) +{ + if (::shutdown(sockfd, how) < 0) + return Error::from_syscall("shutdown"sv, -errno); + return {}; +} + +ErrorOr send(int sockfd, void const* buffer, size_t buffer_length, int flags) +{ + auto sent = ::send(sockfd, buffer, buffer_length, flags); + if (sent < 0) + return Error::from_syscall("send"sv, -errno); + return sent; +} + +ErrorOr sendmsg(int sockfd, const struct msghdr* message, int flags) +{ + auto sent = ::sendmsg(sockfd, message, flags); + if (sent < 0) + return Error::from_syscall("sendmsg"sv, -errno); + return sent; +} + +ErrorOr sendto(int sockfd, void const* source, size_t source_length, int flags, struct sockaddr const* destination, socklen_t destination_length) +{ + auto sent = ::sendto(sockfd, source, source_length, flags, destination, destination_length); + if (sent < 0) + return Error::from_syscall("sendto"sv, -errno); + return sent; +} + +ErrorOr recv(int sockfd, void* buffer, size_t length, int flags) +{ + auto received = ::recv(sockfd, buffer, length, flags); + if (received < 0) + return Error::from_syscall("recv"sv, -errno); + return received; +} + +ErrorOr recvmsg(int sockfd, struct msghdr* message, int flags) +{ + auto received = ::recvmsg(sockfd, message, flags); + if (received < 0) + return Error::from_syscall("recvmsg"sv, -errno); + return received; +} + +ErrorOr recvfrom(int sockfd, void* buffer, size_t buffer_length, int flags, struct sockaddr* address, socklen_t* address_length) +{ + auto received = ::recvfrom(sockfd, buffer, buffer_length, flags, address, address_length); + if (received < 0) + return Error::from_syscall("recvfrom"sv, -errno); + return received; +} + +ErrorOr getsockopt(int sockfd, int level, int option, void* value, socklen_t* value_size) +{ + if (::getsockopt(sockfd, level, option, value, value_size) < 0) + return Error::from_syscall("getsockopt"sv, -errno); + return {}; +} + +ErrorOr setsockopt(int sockfd, int level, int option, void const* value, socklen_t value_size) +{ + if (::setsockopt(sockfd, level, option, value, value_size) < 0) + return Error::from_syscall("setsockopt"sv, -errno); + return {}; +} + +ErrorOr getsockname(int sockfd, struct sockaddr* address, socklen_t* address_length) +{ + if (::getsockname(sockfd, address, address_length) < 0) + return Error::from_syscall("getsockname"sv, -errno); + return {}; +} + +ErrorOr getpeername(int sockfd, struct sockaddr* address, socklen_t* address_length) +{ + if (::getpeername(sockfd, address, address_length) < 0) + return Error::from_syscall("getpeername"sv, -errno); + return {}; +} + +ErrorOr socketpair(int domain, int type, int protocol, int sv[2]) +{ + if (::socketpair(domain, type, protocol, sv) < 0) + return Error::from_syscall("socketpair"sv, -errno); + return {}; +} + } diff --git a/Userland/Libraries/LibCore/System.h b/Userland/Libraries/LibCore/System.h index 92609212b8..e86a795469 100644 --- a/Userland/Libraries/LibCore/System.h +++ b/Userland/Libraries/LibCore/System.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2021, Andreas Kling * Copyright (c) 2021, Kenneth Myhra + * Copyright (c) 2021, Sam Atkins * * SPDX-License-Identifier: BSD-2-Clause */ @@ -8,10 +9,13 @@ #pragma once #include +#include #include #include #include #include +#include +#include #include #include #include @@ -32,6 +36,10 @@ ErrorOr mount(int source_fd, StringView target, StringView fs_type, int fl ErrorOr ptrace(int request, pid_t tid, void* address, void* data); #endif +#ifndef AK_OS_MACOS +ErrorOr accept4(int sockfd, struct sockaddr*, socklen_t*, int flags); +#endif + ErrorOr sigaction(int signal, struct sigaction const* action, struct sigaction* old_action); #ifdef __APPLE__ ErrorOr signal(int signal, sig_t handler); @@ -78,4 +86,22 @@ ErrorOr fchmod(int fd, mode_t mode); ErrorOr rename(StringView old_path, StringView new_path); ErrorOr utime(StringView path, Optional); +ErrorOr socket(int domain, int type, int protocol); +ErrorOr bind(int sockfd, struct sockaddr const*, socklen_t); +ErrorOr listen(int sockfd, int backlog); +ErrorOr accept(int sockfd, struct sockaddr*, socklen_t*); +ErrorOr connect(int sockfd, struct sockaddr const*, socklen_t); +ErrorOr shutdown(int sockfd, int how); +ErrorOr send(int sockfd, void const*, size_t, int flags); +ErrorOr sendmsg(int sockfd, const struct msghdr*, int flags); +ErrorOr sendto(int sockfd, void const*, size_t, int flags, struct sockaddr const*, socklen_t); +ErrorOr recv(int sockfd, void*, size_t, int flags); +ErrorOr recvmsg(int sockfd, struct msghdr*, int flags); +ErrorOr recvfrom(int sockfd, void*, size_t, int flags, struct sockaddr*, socklen_t*); +ErrorOr getsockopt(int sockfd, int level, int option, void* value, socklen_t* value_size); +ErrorOr setsockopt(int sockfd, int level, int option, void const* value, socklen_t value_size); +ErrorOr getsockname(int sockfd, struct sockaddr*, socklen_t*); +ErrorOr getpeername(int sockfd, struct sockaddr*, socklen_t*); +ErrorOr socketpair(int domain, int type, int protocol, int sv[2]); + }