Skip to content

Commit

Permalink
scubainit: Restore the default SIGPIPE action
Browse files Browse the repository at this point in the history
Rust pre-main code may change the SIGPIPE disposition to ignore:
* rust-lang/rust#62569
* rust-lang/rust#97889

We could use the nightly compiler flag -Zon-broken-pipe=inherit to
disable this behavior. Instead, we take the simpler route and restore
the default disposition ourselves.

Fixes #254
  • Loading branch information
JonathonReinhart committed May 20, 2024
1 parent 325fb58 commit bbd1ede
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
19 changes: 19 additions & 0 deletions scubainit/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ fn run_scubainit() -> Result<()> {
setup_logging()?;
info!("Looking Rusty!");

restore_sigpipe_default()?;

let ctx = process_envvars()?;

if let Some(ref user_info) = ctx.user_info {
Expand Down Expand Up @@ -368,3 +370,20 @@ fn setup_logging() -> Result<()> {
.verbosity(verbosity)
.init()?)
}

// Restore the default SIGPIPE action.
// Rust pre-main code may change the SIGPIPE disposition to ignore:
// https://github.com/rust-lang/rust/issues/62569
// https://github.com/rust-lang/rust/issues/97889
fn restore_sigpipe_default() -> Result<()> {
// Set the SIGPIPE disposition to default (terminate).
// SAFETY: No signal handler is provided, only the default action,
// so no additional consideration is needed.
unsafe {
let result = libc::signal(libc::SIGPIPE, libc::SIG_DFL);
if result == libc::SIG_ERR {
return Err(std::io::Error::last_os_error().into())
}
}
Ok(())
}
11 changes: 11 additions & 0 deletions tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,17 @@ def test_redirect_stdin(self) -> None:
assert_str_equalish(out, test_str)


class TestMainSignals(MainTest):
def test_sigpipe(self) -> None:
"""Verify SIGPIPE is handled correctly"""
# See https://github.com/JonathonReinhart/scuba/issues/254
SCUBA_YML.write_text(f"image: {DOCKER_IMAGE}")

out, err = run_scuba(["sh", "-c", "yes | echo abcd"])
assert_str_equalish(out, "abcd")
assert_str_equalish(err, "")


class TestMainUser(MainTest):
def _test_user(
self,
Expand Down

0 comments on commit bbd1ede

Please sign in to comment.