1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 21:47:43 +00:00

Kernel: Add support for MSG_NOSIGNAL and properly send SIGPIPE

Previously we didn't send the SIGPIPE signal to processes when
sendto()/sendmsg()/etc. returned EPIPE. And now we do.

This also adds support for MSG_NOSIGNAL to suppress the signal.
This commit is contained in:
Gunnar Beutner 2022-10-23 10:30:12 +02:00 committed by Linus Groh
parent e5e7ea90b1
commit ce4b66e908
4 changed files with 16 additions and 5 deletions

View file

@ -60,6 +60,7 @@ extern "C" {
#define MSG_DONTROUTE 0x10 #define MSG_DONTROUTE 0x10
#define MSG_WAITALL 0x20 #define MSG_WAITALL 0x20
#define MSG_DONTWAIT 0x40 #define MSG_DONTWAIT 0x40
#define MSG_NOSIGNAL 0x80
typedef uint16_t sa_family_t; typedef uint16_t sa_family_t;

View file

@ -120,10 +120,8 @@ ErrorOr<size_t> FIFO::read(OpenFileDescription& fd, u64, UserOrKernelBuffer& buf
ErrorOr<size_t> FIFO::write(OpenFileDescription& fd, u64, UserOrKernelBuffer const& buffer, size_t size) ErrorOr<size_t> FIFO::write(OpenFileDescription& fd, u64, UserOrKernelBuffer const& buffer, size_t size)
{ {
if (!m_readers) { if (!m_readers)
Thread::current()->send_signal(SIGPIPE, &Process::current());
return EPIPE; return EPIPE;
}
if (!fd.is_blocking() && m_buffer->space_for_writing() == 0) if (!fd.is_blocking() && m_buffer->space_for_writing() == 0)
return EAGAIN; return EAGAIN;

View file

@ -194,8 +194,11 @@ ErrorOr<FlatPtr> Process::sys$sendmsg(int sockfd, Userspace<const struct msghdr*
return ENOTSOCK; return ENOTSOCK;
auto& socket = *description->socket(); auto& socket = *description->socket();
if (socket.is_shut_down_for_writing()) if (socket.is_shut_down_for_writing()) {
if ((flags & MSG_NOSIGNAL) == 0)
Thread::current()->send_signal(SIGPIPE, &Process::current());
return EPIPE; return EPIPE;
}
auto data_buffer = TRY(UserOrKernelBuffer::for_user_buffer((u8*)iovs[0].iov_base, iovs[0].iov_len)); auto data_buffer = TRY(UserOrKernelBuffer::for_user_buffer((u8*)iovs[0].iov_base, iovs[0].iov_len));
while (true) { while (true) {
@ -211,7 +214,14 @@ ErrorOr<FlatPtr> Process::sys$sendmsg(int sockfd, Userspace<const struct msghdr*
// TODO: handle exceptions in unblock_flags // TODO: handle exceptions in unblock_flags
} }
auto bytes_sent = TRY(socket.sendto(*description, data_buffer, iovs[0].iov_len, flags, user_addr, addr_length)); auto bytes_sent_or_error = socket.sendto(*description, data_buffer, iovs[0].iov_len, flags, user_addr, addr_length);
if (bytes_sent_or_error.is_error()) {
if ((flags & MSG_NOSIGNAL) == 0 && bytes_sent_or_error.error().code() == EPIPE)
Thread::current()->send_signal(SIGPIPE, &Process::current());
return bytes_sent_or_error.release_error();
}
auto bytes_sent = bytes_sent_or_error.release_value();
if (bytes_sent > 0) if (bytes_sent > 0)
return bytes_sent; return bytes_sent;
} }

View file

@ -78,6 +78,8 @@ ErrorOr<FlatPtr> Process::do_write(OpenFileDescription& description, UserOrKerne
return total_nwritten; return total_nwritten;
if (nwritten_or_error.error().code() == EAGAIN) if (nwritten_or_error.error().code() == EAGAIN)
continue; continue;
if (nwritten_or_error.error().code() == EPIPE)
Thread::current()->send_signal(SIGPIPE, &Process::current());
return nwritten_or_error.release_error(); return nwritten_or_error.release_error();
} }
VERIFY(nwritten_or_error.value() > 0); VERIFY(nwritten_or_error.value() > 0);