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()
This commit is contained in:
Sam Atkins 2021-12-25 12:52:19 +00:00 committed by Andreas Kling
parent 1fba221b46
commit 289cf8d7ef
Notes: sideshowbarker 2024-07-17 22:06:28 +09:00
2 changed files with 164 additions and 2 deletions

View file

@ -1,6 +1,7 @@
/*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021, Kenneth Myhra <kennethmyhra@gmail.com>
* Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -8,12 +9,10 @@
#include <AK/String.h>
#include <LibCore/System.h>
#include <LibSystem/syscall.h>
#include <fcntl.h>
#include <stdarg.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/ptrace.h>
#include <sys/socket.h>
#include <termios.h>
#include <unistd.h>
@ -115,6 +114,16 @@ ErrorOr<long> ptrace(int request, pid_t tid, void* address, void* data)
}
#endif
#ifndef AK_OS_MACOS
ErrorOr<int> 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<void> sigaction(int signal, struct sigaction const* action, struct sigaction* old_action)
{
if (::sigaction(signal, action, old_action) < 0)
@ -573,4 +582,131 @@ ErrorOr<void> utime(StringView path, Optional<struct utimbuf> maybe_buf)
#endif
}
ErrorOr<int> 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<void> 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<void> listen(int sockfd, int backlog)
{
if (::listen(sockfd, backlog) < 0)
return Error::from_syscall("listen"sv, -errno);
return {};
}
ErrorOr<int> 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<void> 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<void> shutdown(int sockfd, int how)
{
if (::shutdown(sockfd, how) < 0)
return Error::from_syscall("shutdown"sv, -errno);
return {};
}
ErrorOr<ssize_t> 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<ssize_t> 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<ssize_t> 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<ssize_t> 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<ssize_t> 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<ssize_t> 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<void> 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<void> 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<void> 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<void> 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<void> 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 {};
}
}

View file

@ -1,6 +1,7 @@
/*
* Copyright (c) 2021, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021, Kenneth Myhra <kennethmyhra@gmail.com>
* Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -8,10 +9,13 @@
#pragma once
#include <AK/Error.h>
#include <fcntl.h>
#include <grp.h>
#include <pwd.h>
#include <signal.h>
#include <spawn.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <termios.h>
@ -32,6 +36,10 @@ ErrorOr<void> mount(int source_fd, StringView target, StringView fs_type, int fl
ErrorOr<long> ptrace(int request, pid_t tid, void* address, void* data);
#endif
#ifndef AK_OS_MACOS
ErrorOr<int> accept4(int sockfd, struct sockaddr*, socklen_t*, int flags);
#endif
ErrorOr<void> sigaction(int signal, struct sigaction const* action, struct sigaction* old_action);
#ifdef __APPLE__
ErrorOr<sig_t> signal(int signal, sig_t handler);
@ -78,4 +86,22 @@ ErrorOr<void> fchmod(int fd, mode_t mode);
ErrorOr<void> rename(StringView old_path, StringView new_path);
ErrorOr<void> utime(StringView path, Optional<struct utimbuf>);
ErrorOr<int> socket(int domain, int type, int protocol);
ErrorOr<void> bind(int sockfd, struct sockaddr const*, socklen_t);
ErrorOr<void> listen(int sockfd, int backlog);
ErrorOr<int> accept(int sockfd, struct sockaddr*, socklen_t*);
ErrorOr<void> connect(int sockfd, struct sockaddr const*, socklen_t);
ErrorOr<void> shutdown(int sockfd, int how);
ErrorOr<ssize_t> send(int sockfd, void const*, size_t, int flags);
ErrorOr<ssize_t> sendmsg(int sockfd, const struct msghdr*, int flags);
ErrorOr<ssize_t> sendto(int sockfd, void const*, size_t, int flags, struct sockaddr const*, socklen_t);
ErrorOr<ssize_t> recv(int sockfd, void*, size_t, int flags);
ErrorOr<ssize_t> recvmsg(int sockfd, struct msghdr*, int flags);
ErrorOr<ssize_t> recvfrom(int sockfd, void*, size_t, int flags, struct sockaddr*, socklen_t*);
ErrorOr<void> getsockopt(int sockfd, int level, int option, void* value, socklen_t* value_size);
ErrorOr<void> setsockopt(int sockfd, int level, int option, void const* value, socklen_t value_size);
ErrorOr<void> getsockname(int sockfd, struct sockaddr*, socklen_t*);
ErrorOr<void> getpeername(int sockfd, struct sockaddr*, socklen_t*);
ErrorOr<void> socketpair(int domain, int type, int protocol, int sv[2]);
}