mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 10:28:10 +00:00
Kernel: Make all syscall functions return KResultOr<T>
This makes it a lot easier to return errors since we no longer have to worry about negating EFOO errors and can just return them flat.
This commit is contained in:
parent
9af1e1a3bf
commit
ac71775de5
70 changed files with 747 additions and 742 deletions
|
@ -40,12 +40,12 @@ namespace Kernel {
|
|||
REQUIRE_PROMISE(unix); \
|
||||
} while (0)
|
||||
|
||||
int Process::sys$socket(int domain, int type, int protocol)
|
||||
KResultOr<int> Process::sys$socket(int domain, int type, int protocol)
|
||||
{
|
||||
REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(domain);
|
||||
|
||||
if ((type & SOCK_TYPE_MASK) == SOCK_RAW && !is_superuser())
|
||||
return -EACCES;
|
||||
return EACCES;
|
||||
int fd = alloc_fd();
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
@ -66,59 +66,59 @@ int Process::sys$socket(int domain, int type, int protocol)
|
|||
return fd;
|
||||
}
|
||||
|
||||
int Process::sys$bind(int sockfd, Userspace<const sockaddr*> address, socklen_t address_length)
|
||||
KResultOr<int> Process::sys$bind(int sockfd, Userspace<const sockaddr*> address, socklen_t address_length)
|
||||
{
|
||||
auto description = file_description(sockfd);
|
||||
if (!description)
|
||||
return -EBADF;
|
||||
return EBADF;
|
||||
if (!description->is_socket())
|
||||
return -ENOTSOCK;
|
||||
return ENOTSOCK;
|
||||
auto& socket = *description->socket();
|
||||
REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
|
||||
return socket.bind(address, address_length);
|
||||
}
|
||||
|
||||
int Process::sys$listen(int sockfd, int backlog)
|
||||
KResultOr<int> Process::sys$listen(int sockfd, int backlog)
|
||||
{
|
||||
if (backlog < 0)
|
||||
return -EINVAL;
|
||||
return EINVAL;
|
||||
auto description = file_description(sockfd);
|
||||
if (!description)
|
||||
return -EBADF;
|
||||
return EBADF;
|
||||
if (!description->is_socket())
|
||||
return -ENOTSOCK;
|
||||
return ENOTSOCK;
|
||||
auto& socket = *description->socket();
|
||||
REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
|
||||
if (socket.is_connected())
|
||||
return -EINVAL;
|
||||
return EINVAL;
|
||||
return socket.listen(backlog);
|
||||
}
|
||||
|
||||
int Process::sys$accept(int accepting_socket_fd, Userspace<sockaddr*> user_address, Userspace<socklen_t*> user_address_size)
|
||||
KResultOr<int> Process::sys$accept(int accepting_socket_fd, Userspace<sockaddr*> user_address, Userspace<socklen_t*> user_address_size)
|
||||
{
|
||||
REQUIRE_PROMISE(accept);
|
||||
|
||||
socklen_t address_size = 0;
|
||||
if (user_address && !copy_from_user(&address_size, static_ptr_cast<const socklen_t*>(user_address_size)))
|
||||
return -EFAULT;
|
||||
return EFAULT;
|
||||
|
||||
int accepted_socket_fd = alloc_fd();
|
||||
if (accepted_socket_fd < 0)
|
||||
return accepted_socket_fd;
|
||||
auto accepting_socket_description = file_description(accepting_socket_fd);
|
||||
if (!accepting_socket_description)
|
||||
return -EBADF;
|
||||
return EBADF;
|
||||
if (!accepting_socket_description->is_socket())
|
||||
return -ENOTSOCK;
|
||||
return ENOTSOCK;
|
||||
auto& socket = *accepting_socket_description->socket();
|
||||
|
||||
if (!socket.can_accept()) {
|
||||
if (accepting_socket_description->is_blocking()) {
|
||||
auto unblock_flags = Thread::FileBlocker::BlockFlags::None;
|
||||
if (Thread::current()->block<Thread::AcceptBlocker>({}, *accepting_socket_description, unblock_flags).was_interrupted())
|
||||
return -EINTR;
|
||||
return EINTR;
|
||||
} else {
|
||||
return -EAGAIN;
|
||||
return EAGAIN;
|
||||
}
|
||||
}
|
||||
auto accepted_socket = socket.accept();
|
||||
|
@ -129,9 +129,9 @@ int Process::sys$accept(int accepting_socket_fd, Userspace<sockaddr*> user_addre
|
|||
address_size = min(sizeof(sockaddr_un), static_cast<size_t>(address_size));
|
||||
accepted_socket->get_peer_address((sockaddr*)address_buffer, &address_size);
|
||||
if (!copy_to_user(user_address, address_buffer, address_size))
|
||||
return -EFAULT;
|
||||
return EFAULT;
|
||||
if (!copy_to_user(user_address_size, &address_size))
|
||||
return -EFAULT;
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
auto accepted_socket_description_result = FileDescription::create(*accepted_socket);
|
||||
|
@ -150,16 +150,16 @@ int Process::sys$accept(int accepting_socket_fd, Userspace<sockaddr*> user_addre
|
|||
return accepted_socket_fd;
|
||||
}
|
||||
|
||||
int Process::sys$connect(int sockfd, Userspace<const sockaddr*> user_address, socklen_t user_address_size)
|
||||
KResultOr<int> Process::sys$connect(int sockfd, Userspace<const sockaddr*> user_address, socklen_t user_address_size)
|
||||
{
|
||||
int fd = alloc_fd();
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
auto description = file_description(sockfd);
|
||||
if (!description)
|
||||
return -EBADF;
|
||||
return EBADF;
|
||||
if (!description->is_socket())
|
||||
return -ENOTSOCK;
|
||||
return ENOTSOCK;
|
||||
|
||||
auto& socket = *description->socket();
|
||||
REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
|
||||
|
@ -167,79 +167,79 @@ int Process::sys$connect(int sockfd, Userspace<const sockaddr*> user_address, so
|
|||
return socket.connect(*description, user_address, user_address_size, description->is_blocking() ? ShouldBlock::Yes : ShouldBlock::No);
|
||||
}
|
||||
|
||||
int Process::sys$shutdown(int sockfd, int how)
|
||||
KResultOr<int> Process::sys$shutdown(int sockfd, int how)
|
||||
{
|
||||
REQUIRE_PROMISE(stdio);
|
||||
if (how & ~SHUT_RDWR)
|
||||
return -EINVAL;
|
||||
return EINVAL;
|
||||
auto description = file_description(sockfd);
|
||||
if (!description)
|
||||
return -EBADF;
|
||||
return EBADF;
|
||||
if (!description->is_socket())
|
||||
return -ENOTSOCK;
|
||||
return ENOTSOCK;
|
||||
|
||||
auto& socket = *description->socket();
|
||||
REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
|
||||
return socket.shutdown(how);
|
||||
}
|
||||
|
||||
ssize_t Process::sys$sendmsg(int sockfd, Userspace<const struct msghdr*> user_msg, int flags)
|
||||
KResultOr<ssize_t> Process::sys$sendmsg(int sockfd, Userspace<const struct msghdr*> user_msg, int flags)
|
||||
{
|
||||
REQUIRE_PROMISE(stdio);
|
||||
struct msghdr msg;
|
||||
if (!copy_from_user(&msg, user_msg))
|
||||
return -EFAULT;
|
||||
return EFAULT;
|
||||
|
||||
if (msg.msg_iovlen != 1)
|
||||
return -ENOTSUP; // FIXME: Support this :)
|
||||
return ENOTSUP; // FIXME: Support this :)
|
||||
Vector<iovec, 1> iovs;
|
||||
iovs.resize(msg.msg_iovlen);
|
||||
if (!copy_n_from_user(iovs.data(), msg.msg_iov, msg.msg_iovlen))
|
||||
return -EFAULT;
|
||||
return EFAULT;
|
||||
|
||||
Userspace<const sockaddr*> user_addr((FlatPtr)msg.msg_name);
|
||||
socklen_t addr_length = msg.msg_namelen;
|
||||
|
||||
auto description = file_description(sockfd);
|
||||
if (!description)
|
||||
return -EBADF;
|
||||
return EBADF;
|
||||
if (!description->is_socket())
|
||||
return -ENOTSOCK;
|
||||
return ENOTSOCK;
|
||||
auto& socket = *description->socket();
|
||||
if (socket.is_shut_down_for_writing())
|
||||
return -EPIPE;
|
||||
return EPIPE;
|
||||
auto data_buffer = UserOrKernelBuffer::for_user_buffer((u8*)iovs[0].iov_base, iovs[0].iov_len);
|
||||
if (!data_buffer.has_value())
|
||||
return -EFAULT;
|
||||
return EFAULT;
|
||||
auto result = socket.sendto(*description, data_buffer.value(), iovs[0].iov_len, flags, user_addr, addr_length);
|
||||
if (result.is_error())
|
||||
return result.error();
|
||||
return result.value();
|
||||
}
|
||||
|
||||
ssize_t Process::sys$recvmsg(int sockfd, Userspace<struct msghdr*> user_msg, int flags)
|
||||
KResultOr<ssize_t> Process::sys$recvmsg(int sockfd, Userspace<struct msghdr*> user_msg, int flags)
|
||||
{
|
||||
REQUIRE_PROMISE(stdio);
|
||||
|
||||
struct msghdr msg;
|
||||
if (!copy_from_user(&msg, user_msg))
|
||||
return -EFAULT;
|
||||
return EFAULT;
|
||||
|
||||
if (msg.msg_iovlen != 1)
|
||||
return -ENOTSUP; // FIXME: Support this :)
|
||||
return ENOTSUP; // FIXME: Support this :)
|
||||
Vector<iovec, 1> iovs;
|
||||
iovs.resize(msg.msg_iovlen);
|
||||
if (!copy_n_from_user(iovs.data(), msg.msg_iov, msg.msg_iovlen))
|
||||
return -EFAULT;
|
||||
return EFAULT;
|
||||
|
||||
Userspace<sockaddr*> user_addr((FlatPtr)msg.msg_name);
|
||||
Userspace<socklen_t*> user_addr_length(msg.msg_name ? (FlatPtr)&user_msg.unsafe_userspace_ptr()->msg_namelen : 0);
|
||||
|
||||
auto description = file_description(sockfd);
|
||||
if (!description)
|
||||
return -EBADF;
|
||||
return EBADF;
|
||||
if (!description->is_socket())
|
||||
return -ENOTSOCK;
|
||||
return ENOTSOCK;
|
||||
auto& socket = *description->socket();
|
||||
|
||||
if (socket.is_shut_down_for_reading())
|
||||
|
@ -251,7 +251,7 @@ ssize_t Process::sys$recvmsg(int sockfd, Userspace<struct msghdr*> user_msg, int
|
|||
|
||||
auto data_buffer = UserOrKernelBuffer::for_user_buffer((u8*)iovs[0].iov_base, iovs[0].iov_len);
|
||||
if (!data_buffer.has_value())
|
||||
return -EFAULT;
|
||||
return EFAULT;
|
||||
timeval timestamp = { 0, 0 };
|
||||
auto result = socket.recvfrom(*description, data_buffer.value(), iovs[0].iov_len, flags, user_addr, user_addr_length, timestamp);
|
||||
if (flags & MSG_DONTWAIT)
|
||||
|
@ -278,14 +278,14 @@ ssize_t Process::sys$recvmsg(int sockfd, Userspace<struct msghdr*> user_msg, int
|
|||
} else {
|
||||
cmsg_timestamp = { { control_length, SOL_SOCKET, SCM_TIMESTAMP }, timestamp };
|
||||
if (!copy_to_user(msg.msg_control, &cmsg_timestamp, control_length))
|
||||
return -EFAULT;
|
||||
return EFAULT;
|
||||
}
|
||||
if (!copy_to_user(&user_msg.unsafe_userspace_ptr()->msg_controllen, &control_length))
|
||||
return -EFAULT;
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
if (!copy_to_user(&user_msg.unsafe_userspace_ptr()->msg_flags, &msg_flags))
|
||||
return -EFAULT;
|
||||
return EFAULT;
|
||||
|
||||
return result.value();
|
||||
}
|
||||
|
@ -295,17 +295,17 @@ int Process::get_sock_or_peer_name(const Params& params)
|
|||
{
|
||||
socklen_t addrlen_value;
|
||||
if (!copy_from_user(&addrlen_value, params.addrlen, sizeof(socklen_t)))
|
||||
return -EFAULT;
|
||||
return EFAULT;
|
||||
|
||||
if (addrlen_value <= 0)
|
||||
return -EINVAL;
|
||||
return EINVAL;
|
||||
|
||||
auto description = file_description(params.sockfd);
|
||||
if (!description)
|
||||
return -EBADF;
|
||||
return EBADF;
|
||||
|
||||
if (!description->is_socket())
|
||||
return -ENOTSOCK;
|
||||
return ENOTSOCK;
|
||||
|
||||
auto& socket = *description->socket();
|
||||
REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
|
||||
|
@ -317,33 +317,33 @@ int Process::get_sock_or_peer_name(const Params& params)
|
|||
else
|
||||
socket.get_peer_address((sockaddr*)address_buffer, &addrlen_value);
|
||||
if (!copy_to_user(params.addr, address_buffer, addrlen_value))
|
||||
return -EFAULT;
|
||||
return EFAULT;
|
||||
if (!copy_to_user(params.addrlen, &addrlen_value))
|
||||
return -EFAULT;
|
||||
return EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Process::sys$getsockname(Userspace<const Syscall::SC_getsockname_params*> user_params)
|
||||
KResultOr<int> Process::sys$getsockname(Userspace<const Syscall::SC_getsockname_params*> user_params)
|
||||
{
|
||||
Syscall::SC_getsockname_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return -EFAULT;
|
||||
return EFAULT;
|
||||
return get_sock_or_peer_name<true>(params);
|
||||
}
|
||||
|
||||
int Process::sys$getpeername(Userspace<const Syscall::SC_getpeername_params*> user_params)
|
||||
KResultOr<int> Process::sys$getpeername(Userspace<const Syscall::SC_getpeername_params*> user_params)
|
||||
{
|
||||
Syscall::SC_getpeername_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return -EFAULT;
|
||||
return EFAULT;
|
||||
return get_sock_or_peer_name<false>(params);
|
||||
}
|
||||
|
||||
int Process::sys$getsockopt(Userspace<const Syscall::SC_getsockopt_params*> user_params)
|
||||
KResultOr<int> Process::sys$getsockopt(Userspace<const Syscall::SC_getsockopt_params*> user_params)
|
||||
{
|
||||
Syscall::SC_getsockopt_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return -EFAULT;
|
||||
return EFAULT;
|
||||
|
||||
int sockfd = params.sockfd;
|
||||
int level = params.level;
|
||||
|
@ -353,30 +353,30 @@ int Process::sys$getsockopt(Userspace<const Syscall::SC_getsockopt_params*> user
|
|||
|
||||
socklen_t value_size;
|
||||
if (!copy_from_user(&value_size, params.value_size, sizeof(socklen_t)))
|
||||
return -EFAULT;
|
||||
return EFAULT;
|
||||
|
||||
auto description = file_description(sockfd);
|
||||
if (!description)
|
||||
return -EBADF;
|
||||
return EBADF;
|
||||
if (!description->is_socket())
|
||||
return -ENOTSOCK;
|
||||
return ENOTSOCK;
|
||||
auto& socket = *description->socket();
|
||||
|
||||
REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
|
||||
return socket.getsockopt(*description, level, option, user_value, user_value_size);
|
||||
}
|
||||
|
||||
int Process::sys$setsockopt(Userspace<const Syscall::SC_setsockopt_params*> user_params)
|
||||
KResultOr<int> Process::sys$setsockopt(Userspace<const Syscall::SC_setsockopt_params*> user_params)
|
||||
{
|
||||
Syscall::SC_setsockopt_params params;
|
||||
if (!copy_from_user(¶ms, user_params))
|
||||
return -EFAULT;
|
||||
return EFAULT;
|
||||
Userspace<const void*> user_value((FlatPtr)params.value);
|
||||
auto description = file_description(params.sockfd);
|
||||
if (!description)
|
||||
return -EBADF;
|
||||
return EBADF;
|
||||
if (!description->is_socket())
|
||||
return -ENOTSOCK;
|
||||
return ENOTSOCK;
|
||||
auto& socket = *description->socket();
|
||||
REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(socket.domain());
|
||||
return socket.setsockopt(params.level, params.option, user_value, params.value_size);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue