Skip to content

Commit 847fff3

Browse files
committed
uucore: centralize SIGPIPE handling in main macro
1 parent cbbff30 commit 847fff3

15 files changed

Lines changed: 49 additions & 64 deletions

File tree

src/uu/cat/src/cat.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -218,13 +218,6 @@ mod options {
218218

219219
#[uucore::main]
220220
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
221-
// When we receive a SIGPIPE signal, we want to terminate the process so
222-
// that we don't print any error messages to stderr. Rust ignores SIGPIPE
223-
// (see https://github.com/rust-lang/rust/issues/62569), so we restore it's
224-
// default action here.
225-
#[cfg(not(target_os = "windows"))]
226-
let _ = uucore::signals::enable_pipe_errors();
227-
228221
let matches = uucore::clap_localization::handle_clap_result(uu_app(), args)?;
229222

230223
let number_mode = if matches.get_flag(options::NUMBER_NONBLANK) {

src/uu/dd/src/dd.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
55

66
// spell-checker:ignore fname, ftype, tname, fpath, specfile, testfile, unspec, ifile, ofile, outfile, fullblock, urand, fileio, atoe, atoibm, behaviour, bmax, bremain, cflags, creat, ctable, ctty, datastructures, doesnt, etoa, fileout, fname, gnudd, iconvflags, iseek, nocache, noctty, noerror, nofollow, nolinks, nonblock, oconvflags, oseek, outfile, parseargs, rlen, rmax, rremain, rsofar, rstat, sigusr, wlen, wstat seekable oconv canonicalized fadvise Fadvise FADV DONTNEED ESPIPE bufferedoutput, SETFL
77

8-
#[cfg(unix)]
9-
uucore::init_startup_state_capture!();
10-
118
mod blocks;
129
mod bufferedoutput;
1310
mod conversion_tables;

src/uu/env/src/env.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,10 +1095,6 @@ fn list_signal_handling(log: &SignalActionLog) {
10951095

10961096
#[uucore::main]
10971097
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
1098-
// Rust ignores SIGPIPE (see https://github.com/rust-lang/rust/issues/62569).
1099-
// We restore its default action here.
1100-
#[cfg(unix)]
1101-
let _ = uucore::signals::enable_pipe_errors();
11021098
EnvAppData::default().run_env(args)
11031099
}
11041100

src/uu/seq/src/seq.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -92,22 +92,8 @@ fn select_precision(
9292
}
9393
}
9494

95-
// Initialize SIGPIPE state capture at process startup (Unix only)
96-
#[cfg(unix)]
97-
uucore::init_startup_state_capture!();
98-
9995
#[uucore::main]
10096
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
101-
// Restore SIGPIPE to default if it wasn't explicitly ignored by parent.
102-
// The Rust runtime ignores SIGPIPE, but we need to respect the parent's
103-
// signal disposition for proper pipeline behavior (GNU compatibility).
104-
#[cfg(unix)]
105-
if !signals::sigpipe_was_ignored() {
106-
// Ignore the return value: if setting signal handler fails, we continue anyway.
107-
// The worst case is we don't get proper SIGPIPE behavior, but seq will still work.
108-
let _ = signals::enable_pipe_errors();
109-
}
110-
11197
let matches =
11298
uucore::clap_localization::handle_clap_result(uu_app(), split_short_args_with_value(args))?;
11399

src/uu/split/src/split.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,16 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
5454
let matches = uucore::clap_localization::handle_clap_result(uu_app(), args)?;
5555

5656
match Settings::from(&matches, obs_lines.as_deref()) {
57-
Ok(settings) => split(&settings),
57+
Ok(settings) => {
58+
// When using --filter, we write to a child process's stdin which may
59+
// close early. Disable SIGPIPE so we get EPIPE errors instead of
60+
// being terminated, allowing graceful handling of broken pipes.
61+
#[cfg(unix)]
62+
if settings.filter.is_some() {
63+
let _ = uucore::signals::disable_pipe_errors();
64+
}
65+
split(&settings)
66+
}
5867
Err(e) if e.requires_usage() => Err(UUsageError::new(1, format!("{e}"))),
5968
Err(e) => Err(USimpleError::new(1, format!("{e}"))),
6069
}

src/uu/tac/src/tac.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
// file that was distributed with this source code.
55

66
// spell-checker:ignore (ToDO) sbytes slen dlen memmem memmap Mmap mmap SIGBUS
7-
#[cfg(unix)]
8-
uucore::init_startup_state_capture!();
97

108
mod error;
119

src/uu/tail/src/tail.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,8 @@ use uucore::translate;
3838

3939
use uucore::{show, show_error};
4040

41-
#[cfg(unix)]
42-
uucore::init_startup_state_capture!();
43-
4441
#[uucore::main]
4542
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
46-
// When we receive a SIGPIPE signal, we want to terminate the process so
47-
// that we don't print any error messages to stderr. Rust ignores SIGPIPE
48-
// (see https://github.com/rust-lang/rust/issues/62569), so we restore it's
49-
// default action here.
50-
#[cfg(not(target_os = "windows"))]
51-
let _ = uucore::signals::enable_pipe_errors();
52-
5343
let settings = parse_args(args)?;
5444

5545
settings.check_warnings();

src/uu/tee/src/tee.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use uucore::{format_usage, show_error};
1919
#[cfg(target_os = "linux")]
2020
use uucore::signals::ensure_stdout_not_broken;
2121
#[cfg(unix)]
22-
use uucore::signals::{enable_pipe_errors, ignore_interrupts};
22+
use uucore::signals::{disable_pipe_errors, ignore_interrupts};
2323

2424
mod options {
2525
pub const APPEND: &str = "append";
@@ -163,8 +163,8 @@ fn tee(options: &Options) -> Result<()> {
163163
if options.ignore_interrupts {
164164
ignore_interrupts().map_err(|_| Error::from(ErrorKind::Other))?;
165165
}
166-
if options.output_error.is_none() {
167-
enable_pipe_errors().map_err(|_| Error::from(ErrorKind::Other))?;
166+
if options.output_error.is_some() {
167+
disable_pipe_errors().map_err(|_| Error::from(ErrorKind::Other))?;
168168
}
169169
}
170170
let mut writers: Vec<NamedWriter> = options

src/uu/timeout/src/timeout.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
// file that was distributed with this source code.
55

66
// spell-checker:ignore (ToDO) tstr sigstr cmdname setpgid sigchld getpid
7-
#[cfg(unix)]
8-
uucore::init_startup_state_capture!();
97

108
mod status;
119

@@ -22,9 +20,6 @@ use uucore::parser::parse_time;
2220
use uucore::process::ChildExt;
2321
use uucore::translate;
2422

25-
#[cfg(unix)]
26-
use uucore::signals::enable_pipe_errors;
27-
2823
use uucore::{
2924
format_usage, show_error,
3025
signals::{signal_by_name_or_value, signal_name_by_value},
@@ -334,8 +329,6 @@ fn timeout(
334329
if !foreground {
335330
let _ = setpgid(Pid::from_raw(0), Pid::from_raw(0));
336331
}
337-
#[cfg(unix)]
338-
enable_pipe_errors()?;
339332

340333
let mut command = process::Command::new(&cmd[0]);
341334
command

src/uu/tr/src/tr.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,6 @@ mod options {
3131

3232
#[uucore::main]
3333
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
34-
// When we receive a SIGPIPE signal, we want to terminate the process so
35-
// that we don't print any error messages to stderr. Rust ignores SIGPIPE
36-
// (see https://github.com/rust-lang/rust/issues/62569), so we restore it's
37-
// default action here.
38-
#[cfg(not(target_os = "windows"))]
39-
let _ = uucore::signals::enable_pipe_errors();
40-
4134
let matches = uucore::clap_localization::handle_clap_result(uu_app(), args)?;
4235

4336
let delete_flag = matches.get_flag(options::DELETE);

0 commit comments

Comments
 (0)