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:
parent
e5e7ea90b1
commit
ce4b66e908
4 changed files with 16 additions and 5 deletions
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue