diff --git a/src/libos/src/error/mod.rs b/src/libos/src/error/mod.rs index 14bc33ab..e01eff8c 100644 --- a/src/libos/src/error/mod.rs +++ b/src/libos/src/error/mod.rs @@ -51,3 +51,20 @@ macro_rules! try_libc { ret }}; } + +// return Err(errno) if libc return -1 +// raise SIGPIPE if errno == EPIPE +macro_rules! try_libc_may_epipe { + ($ret: expr) => {{ + let ret = unsafe { $ret }; + if ret < 0 { + let errno = unsafe { libc::errno() }; + if errno == Errno::EPIPE as i32 { + // SIGPIPE = 12 + crate::signal::do_tkill(current!().tid(), 12); + } + return_errno!(Errno::from(errno as u32), "libc error"); + } + ret + }}; +} diff --git a/src/libos/src/net/socket_file/mod.rs b/src/libos/src/net/socket_file/mod.rs index 88721761..243e8d77 100644 --- a/src/libos/src/net/socket_file/mod.rs +++ b/src/libos/src/net/socket_file/mod.rs @@ -59,7 +59,7 @@ impl File for SocketFile { fn write(&self, buf: &[u8]) -> Result { let (buf_ptr, buf_len) = buf.as_ptr_and_len(); - let ret = try_libc!(libc::ocall::write( + let ret = try_libc_may_epipe!(libc::ocall::write( self.host_fd, buf_ptr as *const c_void, buf_len diff --git a/src/libos/src/net/socket_file/send.rs b/src/libos/src/net/socket_file/send.rs index 7d5d98d3..d3594633 100644 --- a/src/libos/src/net/socket_file/send.rs +++ b/src/libos/src/net/socket_file/send.rs @@ -56,10 +56,10 @@ impl SocketFile { let (msg_control, msg_controllen) = control.as_ptr_and_len(); let msg_control = msg_control as *const c_void; // Flags - let flags = flags.bits(); + let raw_flags = flags.bits(); - let bytes_sent = try_libc!({ - // Do OCall + // Do OCall + unsafe { let status = occlum_ocall_sendmsg( &mut retval as *mut isize, host_fd, @@ -69,12 +69,17 @@ impl SocketFile { msg_iovlen, msg_control, msg_controllen, - flags, + raw_flags, ); assert!(status == sgx_status_t::SGX_SUCCESS); + } + + let bytes_sent = if flags.contains(SendFlags::MSG_NOSIGNAL) { + try_libc!(retval) + } else { + try_libc_may_epipe!(retval) + }; - retval - }); debug_assert!(bytes_sent >= 0); Ok(bytes_sent as usize) } diff --git a/src/libos/src/net/syscalls.rs b/src/libos/src/net/syscalls.rs index fa91e513..94ecdeeb 100644 --- a/src/libos/src/net/syscalls.rs +++ b/src/libos/src/net/syscalls.rs @@ -286,7 +286,7 @@ pub fn do_sendto( let file_ref = current!().file(fd as FileDesc)?; if let Ok(socket) = file_ref.as_socket() { // TODO: check addr and addr_len according to connection mode - let ret = try_libc!(libc::ocall::sendto( + let ret = try_libc_may_epipe!(libc::ocall::sendto( socket.fd(), base, len, diff --git a/src/pal/src/pal_api.c b/src/pal/src/pal_api.c index d10ea308..1d043571 100644 --- a/src/pal/src/pal_api.c +++ b/src/pal/src/pal_api.c @@ -36,12 +36,10 @@ int occlum_pal_init(const struct occlum_pal_attr *attr) { errno = EEXIST; return -1; } -// FIXME -#ifndef SGX_MODE_SIM + if (pal_register_sig_handlers() < 0) { return -1; } -#endif if (pal_init_enclave(resolved_path) < 0) { return -1; diff --git a/src/pal/src/pal_sig_handler.c b/src/pal/src/pal_sig_handler.c index 995c6b37..108236fd 100644 --- a/src/pal/src/pal_sig_handler.c +++ b/src/pal/src/pal_sig_handler.c @@ -7,12 +7,16 @@ #define SIGRT_INTERRUPT 64 int pal_register_sig_handlers(void) { - struct sigaction action; - action.sa_handler = SIG_IGN; - memset(&action.sa_mask, 0, sizeof(action.sa_mask)); - action.sa_flags = 0; - if (sigaction(SIGRT_INTERRUPT, &action, NULL) < 0) { - PAL_ERROR("Failed to regiter signal handlers"); + // FIXME: enable interruptable signal in SIM mode +#ifndef SGX_MODE_SIM + if (signal(SIGRT_INTERRUPT, SIG_IGN) == SIG_ERR) { + PAL_ERROR("Failed to regiter the SIG64 handler"); + return -1; + } +#endif + + if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) { + PAL_ERROR("Failed to regiter the SIGPIPE handler"); return -1; } return 0;