Skip to content

Commit 426ab14

Browse files
committed
Set MSG_NOSIGNAL for UnixSteam
#139956 fix
1 parent ed44c0e commit 426ab14

File tree

3 files changed

+36
-1
lines changed

3 files changed

+36
-1
lines changed

library/std/src/net/tcp.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ use crate::time::Duration;
5353
/// Ok(())
5454
/// } // the stream is closed here
5555
/// ```
56+
///
57+
/// # Platform-specific Behavior
58+
///
59+
/// On Unix, writes to the underlying socket in `SOCK_STREAM` mode are made with
60+
/// `MSG_NOSIGNAL` flag. This suppresses the emission of the `SIGPIPE` signal when writing
61+
/// to disconnected socket. In some cases, getting a `SIGPIPE` would trigger process termination.
5662
#[stable(feature = "rust1", since = "1.0.0")]
5763
pub struct TcpStream(net_imp::TcpStream);
5864

library/std/src/os/unix/net/stream.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
cfg_if::cfg_if! {
2+
if #[cfg(any(
3+
target_os = "linux", target_os = "android",
4+
target_os = "hurd",
5+
target_os = "dragonfly", target_os = "freebsd",
6+
target_os = "openbsd", target_os = "netbsd",
7+
target_os = "solaris", target_os = "illumos",
8+
target_os = "haiku", target_os = "nto",
9+
target_os = "cygwin"))] {
10+
use libc::MSG_NOSIGNAL;
11+
} else {
12+
const MSG_NOSIGNAL: core::ffi::c_int = 0x0;
13+
}
14+
}
15+
116
use super::{SocketAddr, sockaddr_un};
217
#[cfg(any(doc, target_os = "android", target_os = "linux"))]
318
use super::{SocketAncillary, recv_vectored_with_ancillary_from, send_vectored_with_ancillary_to};
@@ -41,6 +56,12 @@ use crate::time::Duration;
4156
/// Ok(())
4257
/// }
4358
/// ```
59+
///
60+
/// # `SIGPIPE`
61+
///
62+
/// Writes to the underlying socket in `SOCK_STREAM` mode are made with `MSG_NOSIGNAL` flag.
63+
/// This suppresses the emission of the `SIGPIPE` signal when writing to disconnected socket.
64+
/// In some cases getting a `SIGPIPE` would trigger process termination.
4465
#[stable(feature = "unix_socket", since = "1.10.0")]
4566
pub struct UnixStream(pub(super) Socket);
4667

@@ -633,7 +654,7 @@ impl io::Write for UnixStream {
633654
#[stable(feature = "unix_socket", since = "1.10.0")]
634655
impl<'a> io::Write for &'a UnixStream {
635656
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
636-
self.0.write(buf)
657+
self.0.send_with_flags(buf, MSG_NOSIGNAL)
637658
}
638659

639660
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {

library/std/src/sys/net/connection/socket/unix.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,14 @@ impl Socket {
281281
self.0.duplicate().map(Socket)
282282
}
283283

284+
pub fn send_with_flags(&self, buf: &[u8], flags: c_int) -> io::Result<usize> {
285+
let len = cmp::min(buf.len(), <wrlen_t>::MAX as usize) as wrlen_t;
286+
let ret = cvt(unsafe {
287+
libc::send(self.as_raw_fd(), buf.as_ptr() as *const c_void, len, flags)
288+
})?;
289+
Ok(ret as usize)
290+
}
291+
284292
fn recv_with_flags(&self, mut buf: BorrowedCursor<'_>, flags: c_int) -> io::Result<()> {
285293
let ret = cvt(unsafe {
286294
libc::recv(

0 commit comments

Comments
 (0)