diff --git a/Kernel/API/POSIX/sys/socket.h b/Kernel/API/POSIX/sys/socket.h index b13cebeb83..b6ee4ac895 100644 --- a/Kernel/API/POSIX/sys/socket.h +++ b/Kernel/API/POSIX/sys/socket.h @@ -60,6 +60,7 @@ extern "C" { #define MSG_DONTROUTE 0x10 #define MSG_WAITALL 0x20 #define MSG_DONTWAIT 0x40 +#define MSG_NOSIGNAL 0x80 typedef uint16_t sa_family_t; diff --git a/Kernel/FileSystem/FIFO.cpp b/Kernel/FileSystem/FIFO.cpp index a351ac4d87..4d8002cca5 100644 --- a/Kernel/FileSystem/FIFO.cpp +++ b/Kernel/FileSystem/FIFO.cpp @@ -120,10 +120,8 @@ ErrorOr FIFO::read(OpenFileDescription& fd, u64, UserOrKernelBuffer& buf ErrorOr FIFO::write(OpenFileDescription& fd, u64, UserOrKernelBuffer const& buffer, size_t size) { - if (!m_readers) { - Thread::current()->send_signal(SIGPIPE, &Process::current()); + if (!m_readers) return EPIPE; - } if (!fd.is_blocking() && m_buffer->space_for_writing() == 0) return EAGAIN; diff --git a/Kernel/Syscalls/socket.cpp b/Kernel/Syscalls/socket.cpp index 65bdb4e759..e02e78bb10 100644 --- a/Kernel/Syscalls/socket.cpp +++ b/Kernel/Syscalls/socket.cpp @@ -194,8 +194,11 @@ ErrorOr Process::sys$sendmsg(int sockfd, Userspacesocket(); - 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; + } auto data_buffer = TRY(UserOrKernelBuffer::for_user_buffer((u8*)iovs[0].iov_base, iovs[0].iov_len)); while (true) { @@ -211,7 +214,14 @@ ErrorOr Process::sys$sendmsg(int sockfd, Userspacesend_signal(SIGPIPE, &Process::current()); + return bytes_sent_or_error.release_error(); + } + + auto bytes_sent = bytes_sent_or_error.release_value(); if (bytes_sent > 0) return bytes_sent; } diff --git a/Kernel/Syscalls/write.cpp b/Kernel/Syscalls/write.cpp index fef524bb75..666fdb9f63 100644 --- a/Kernel/Syscalls/write.cpp +++ b/Kernel/Syscalls/write.cpp @@ -78,6 +78,8 @@ ErrorOr Process::do_write(OpenFileDescription& description, UserOrKerne return total_nwritten; if (nwritten_or_error.error().code() == EAGAIN) continue; + if (nwritten_or_error.error().code() == EPIPE) + Thread::current()->send_signal(SIGPIPE, &Process::current()); return nwritten_or_error.release_error(); } VERIFY(nwritten_or_error.value() > 0);