diff --git a/litebox_shim_linux/src/syscalls/file.rs b/litebox_shim_linux/src/syscalls/file.rs index 46971a4cf..465a0cf88 100644 --- a/litebox_shim_linux/src/syscalls/file.rs +++ b/litebox_shim_linux/src/syscalls/file.rs @@ -18,11 +18,11 @@ use litebox::{ }; use litebox_common_linux::{ AtFlags, EfdFlags, EpollCreateFlags, FcntlArg, FileDescriptorFlags, FileStat, IoReadVec, - IoWriteVec, IoctlArg, TimeParam, errno::Errno, + IoWriteVec, IoctlArg, TimeParam, errno::Errno, signal::Signal, }; use litebox_platform_multiplex::Platform; -use crate::{ConstPtr, GlobalState, MutPtr, ShimFS, Task}; +use crate::{ConstPtr, GlobalState, MutPtr, ShimFS, Task, syscalls::signal::siginfo_kill}; use core::sync::atomic::{AtomicUsize, Ordering}; /// Task state shared by `CLONE_FS`. @@ -420,7 +420,7 @@ impl Task { ) .flatten(); if let Err(Errno::EPIPE) = res { - unimplemented!("send SIGPIPE to the current task"); + self.send_signal(Signal::SIGPIPE, siginfo_kill(Signal::SIGPIPE)); } res } @@ -671,7 +671,7 @@ impl Task { ) .flatten(); if let Err(Errno::EPIPE) = res { - unimplemented!("send SIGPIPE to the current task"); + self.send_signal(Signal::SIGPIPE, siginfo_kill(Signal::SIGPIPE)); } res } diff --git a/litebox_shim_linux/src/syscalls/net.rs b/litebox_shim_linux/src/syscalls/net.rs index ef5d571f1..2b17643e7 100644 --- a/litebox_shim_linux/src/syscalls/net.rs +++ b/litebox_shim_linux/src/syscalls/net.rs @@ -28,11 +28,11 @@ use litebox::{ }; use litebox_common_linux::{ AddressFamily, FileDescriptorFlags, IPProtocol, ReceiveFlags, SendFlags, SockFlags, SockType, - SocketOption, SocketOptionName, TcpOption, UnixProtocol, errno::Errno, + SocketOption, SocketOptionName, TcpOption, UnixProtocol, errno::Errno, signal::Signal, }; use zerocopy::{FromBytes, IntoBytes}; -use crate::{ConstPtr, MutPtr}; +use crate::{ConstPtr, MutPtr, syscalls::signal::siginfo_kill}; use crate::{GlobalState, ShimFS, Task}; use crate::{ Platform, @@ -735,7 +735,8 @@ impl GlobalState { } // Convert `SendFlags` to `litebox::net::SendFlags` - // `DONTWAIT` and `NOSIGNAL` are handled in this function so we don't convert them. + // `DONTWAIT` is handled in this function and `NOSIGNAL` should be handled by caller, + // so we don't convert them. let new_flags = convert_flags!( flags, SendFlags, @@ -751,8 +752,7 @@ impl GlobalState { let is_nonblock = self.get_status(fd).contains(OFlags::NONBLOCK) || flags.contains(SendFlags::DONTWAIT); - let ret = cx - .with_timeout(timeout) + cx.with_timeout(timeout) .wait_on_events( is_nonblock, Events::OUT, @@ -766,13 +766,7 @@ impl GlobalState { Err(e) => Err(TryOpError::Other(Errno::from(e))), }, ) - .map_err(Errno::from); - if let Err(Errno::EPIPE) = ret - && !flags.contains(SendFlags::NOSIGNAL) - { - unimplemented!("send signal SIGPIPE on EPIPE"); - } - ret + .map_err(Errno::from) } /// Receive data via socket channel (lock-free path). @@ -1345,7 +1339,7 @@ impl Task { flags: SendFlags, sockaddr: Option, ) -> Result { - self.files.borrow().with_socket( + let res = self.files.borrow().with_socket( &self.global, sockfd, |fd| { @@ -1363,7 +1357,13 @@ impl Task { .transpose()?; file.sendto(self, buf, flags, addr) }, - ) + ); + if let Err(Errno::EPIPE) = res + && !flags.contains(SendFlags::NOSIGNAL) + { + self.send_signal(Signal::SIGPIPE, siginfo_kill(Signal::SIGPIPE)); + } + res } /// Handle syscall `sendmsg` @@ -1404,7 +1404,7 @@ impl Task { .msg_iov .to_owned_slice(msg.msg_iovlen) .ok_or(Errno::EFAULT)?; - self.files.borrow().with_socket( + let res = self.files.borrow().with_socket( &self.global, sockfd, |fd| { @@ -1445,7 +1445,13 @@ impl Task { } Ok(total_sent) }, - ) + ); + if let Err(Errno::EPIPE) = res + && !flags.contains(SendFlags::NOSIGNAL) + { + self.send_signal(Signal::SIGPIPE, siginfo_kill(Signal::SIGPIPE)); + } + res } /// Handle syscall `recvfrom` diff --git a/litebox_shim_linux/src/syscalls/unix.rs b/litebox_shim_linux/src/syscalls/unix.rs index 6aec592d8..4ee38ec4b 100644 --- a/litebox_shim_linux/src/syscalls/unix.rs +++ b/litebox_shim_linux/src/syscalls/unix.rs @@ -1241,21 +1241,14 @@ impl UnixSocket { let is_nonblocking = flags.contains(SendFlags::DONTWAIT) || self.get_status().contains(OFlags::NONBLOCK); let timeout = self.options.lock().send_timeout; - let ret = match &self.inner { + match &self.inner { UnixSocketInner::Stream(stream) => { stream.sendto(&task.wait_cx(), timeout, buf, is_nonblocking, addr) } UnixSocketInner::Datagram(datagram) => { datagram.sendto(task, timeout, buf, is_nonblocking, addr) } - }; - if let Err(Errno::EPIPE) = ret - && !flags.contains(SendFlags::NOSIGNAL) - { - // TODO: send SIGPIPE signal - unimplemented!("send SIGPIPE on EPIPE"); } - ret } pub(super) fn recvfrom(