From ddee45e1d7fd34563c13513d974f792fae41a2f7 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Tue, 5 Jul 2022 19:56:22 +0200 Subject: Support `#[unix_sigpipe = "inherit|sig_dfl|sig_ign"]` on `fn main()` This makes it possible to instruct libstd to never touch the signal handler for `SIGPIPE`, which makes programs pipeable by default (e.g. with `./your-program | head -n 1`) without `ErrorKind::BrokenPipe` errors. --- compiler/rustc_session/src/config.rs | 12 +++++++++++- compiler/rustc_session/src/config/sigpipe.rs | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 compiler/rustc_session/src/config/sigpipe.rs (limited to 'compiler/rustc_session/src') diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 162fc9aa0a6..e7c8538300e 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -36,6 +36,8 @@ use std::iter::{self, FromIterator}; use std::path::{Path, PathBuf}; use std::str::{self, FromStr}; +pub mod sigpipe; + /// The different settings that the `-C strip` flag can have. #[derive(Clone, Copy, PartialEq, Hash, Debug)] pub enum Strip { @@ -798,7 +800,15 @@ impl UnstableOptions { // The type of entry function, so users can have their own entry functions #[derive(Copy, Clone, PartialEq, Hash, Debug, HashStable_Generic)] pub enum EntryFnType { - Main, + Main { + /// Specifies what to do with `SIGPIPE` before calling `fn main()`. + /// + /// What values that are valid and what they mean must be in sync + /// across rustc and libstd, but we don't want it public in libstd, + /// so we take a bit of an unusual approach with simple constants + /// and an `include!()`. + sigpipe: u8, + }, Start, } diff --git a/compiler/rustc_session/src/config/sigpipe.rs b/compiler/rustc_session/src/config/sigpipe.rs new file mode 100644 index 00000000000..31a3d9de05b --- /dev/null +++ b/compiler/rustc_session/src/config/sigpipe.rs @@ -0,0 +1,20 @@ +/// Do not touch `SIGPIPE`. Use whatever the parent process uses. +#[allow(dead_code)] +pub const INHERIT: u8 = 1; + +/// Change `SIGPIPE` to `SIG_IGN` so that failed writes results in `EPIPE` +/// that are eventually converted to `ErrorKind::BrokenPipe`. +#[allow(dead_code)] +pub const SIG_IGN: u8 = 2; + +/// Change `SIGPIPE` to `SIG_DFL` so that the process is killed when trying +/// to write to a closed pipe. This is usually the desired behavior for CLI +/// apps that produce textual output that you want to pipe to other programs +/// such as `head -n 1`. +#[allow(dead_code)] +pub const SIG_DFL: u8 = 3; + +/// `SIG_IGN` has been the Rust default since 2014. See +/// . +#[allow(dead_code)] +pub const DEFAULT: u8 = SIG_IGN; -- cgit 1.4.1-3-g733a5 From 236903f7e9045717d7795ab12bdf349ccf276c3b Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Wed, 31 Aug 2022 18:04:15 +0200 Subject: unix_sigpipe: Inline compiler sigpipe constants in std --- compiler/rustc_session/src/config/sigpipe.rs | 2 ++ library/std/src/sys/unix/mod.rs | 12 +++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) (limited to 'compiler/rustc_session/src') diff --git a/compiler/rustc_session/src/config/sigpipe.rs b/compiler/rustc_session/src/config/sigpipe.rs index 31a3d9de05b..a5c94118a47 100644 --- a/compiler/rustc_session/src/config/sigpipe.rs +++ b/compiler/rustc_session/src/config/sigpipe.rs @@ -1,3 +1,5 @@ +//! NOTE: Keep these constants in sync with `library/std/src/sys/unix/mod.rs`! + /// Do not touch `SIGPIPE`. Use whatever the parent process uses. #[allow(dead_code)] pub const INHERIT: u8 = 1; diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs index e11201f60ff..d701f950e86 100644 --- a/library/std/src/sys/unix/mod.rs +++ b/library/std/src/sys/unix/mod.rs @@ -155,10 +155,16 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { unsafe fn reset_sigpipe(#[allow(unused_variables)] sigpipe: u8) { #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia", target_os = "horizon")))] { - // We don't want to add this as a public type to libstd, nor do we want to - // duplicate the code, so we choose to include this compiler file like this. + // We don't want to add this as a public type to libstd, nor do we + // want to `include!` a file from the compiler (which would break + // Miri and xargo for example), so we choose to duplicate these + // constants from `compiler/rustc_session/src/config/sigpipe.rs`. + // See the other file for docs. NOTE: Make sure to keep them in + // sync! mod sigpipe { - include!("../../../../../compiler/rustc_session/src/config/sigpipe.rs"); + pub const INHERIT: u8 = 1; + pub const SIG_IGN: u8 = 2; + pub const SIG_DFL: u8 = 3; } let handler = match sigpipe { -- cgit 1.4.1-3-g733a5