env: reraise signal from child process

This commit is contained in:
Terts Diepraam 2022-10-08 18:44:57 +02:00
parent d78089ea53
commit ca820bf674
3 changed files with 24 additions and 20 deletions

1
Cargo.lock generated
View file

@ -2277,6 +2277,7 @@ name = "uu_env"
version = "0.0.15" version = "0.0.15"
dependencies = [ dependencies = [
"clap", "clap",
"nix",
"rust-ini", "rust-ini",
"uucore", "uucore",
] ]

View file

@ -19,6 +19,10 @@ clap = { version = "3.2", features = ["wrap_help", "cargo"] }
rust-ini = "0.18.0" rust-ini = "0.18.0"
uucore = { version=">=0.0.15", package="uucore", path="../../uucore", features=["signals"]} uucore = { version=">=0.0.15", package="uucore", path="../../uucore", features=["signals"]}
[target.'cfg(unix)'.dependencies]
nix = { version = "0.25", default-features = false, features = ["signal"] }
[[bin]] [[bin]]
name = "env" name = "env"
path = "src/main.rs" path = "src/main.rs"

39
src/uu/env/src/env.rs vendored
View file

@ -8,7 +8,7 @@
/* last synced with: env (GNU coreutils) 8.13 */ /* last synced with: env (GNU coreutils) 8.13 */
// spell-checker:ignore (ToDO) chdir execvp progname subcommand subcommands unsets setenv putenv spawnp // spell-checker:ignore (ToDO) chdir execvp progname subcommand subcommands unsets setenv putenv spawnp SIGSEGV SIGBUS sigaction
#[macro_use] #[macro_use]
extern crate clap; extern crate clap;
@ -18,6 +18,8 @@ extern crate uucore;
use clap::{Arg, Command}; use clap::{Arg, Command};
use ini::Ini; use ini::Ini;
#[cfg(unix)]
use nix::sys::signal::{raise, sigaction, SaFlags, SigAction, SigHandler, SigSet, Signal};
use std::borrow::Cow; use std::borrow::Cow;
use std::env; use std::env;
use std::io::{self, Write}; use std::io::{self, Write};
@ -28,8 +30,6 @@ use std::process;
use uucore::display::Quotable; use uucore::display::Quotable;
use uucore::error::{UClapError, UResult, USimpleError, UUsageError}; use uucore::error::{UClapError, UResult, USimpleError, UUsageError};
use uucore::format_usage; use uucore::format_usage;
#[cfg(unix)]
use uucore::signals::signal_name_by_value;
const ABOUT: &str = "set each NAME to VALUE in the environment and run COMMAND"; const ABOUT: &str = "set each NAME to VALUE in the environment and run COMMAND";
const USAGE: &str = "{} [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]"; const USAGE: &str = "{} [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]";
@ -323,24 +323,23 @@ fn run_env(args: impl uucore::Args) -> UResult<()> {
// See std::os::unix::process::ExitStatusExt for more information. This prints out // See std::os::unix::process::ExitStatusExt for more information. This prints out
// the interrupted process and the signal it received. // the interrupted process and the signal it received.
let signal_code = exit.signal().unwrap(); let signal_code = exit.signal().unwrap();
eprintln!( let signal = Signal::try_from(signal_code).unwrap();
"\"{}\" terminated by signal {}",
{ // We have to disable any handler that's installed by default.
let mut command = uucore::util_name().to_owned(); // This ensures that we exit on this signal.
command.push(' '); // For example, `SIGSEGV` and `SIGBUS` have default handlers installed in Rust.
command.push_str(&opts.program.join(" ")); // We ignore the errors because there is not much we can do if that fails anyway.
command // SAFETY: The function is unsafe because installing functions is unsafe, but we are
}, // just defaulting to default behavior and not installing a function. Hence, the call
signal_name_by_value(signal_code as usize).map_or_else( // is safe.
|| String::from("UNKNOWN"), let _ = unsafe {
|signal| { sigaction(
let mut full_signal_name = String::from("SIG"); signal,
full_signal_name.push_str(signal); &SigAction::new(SigHandler::SigDfl, SaFlags::empty(), SigSet::all()),
full_signal_name
}
) )
); };
return Err((128 + signal_code).into());
let _ = raise(signal);
} }
#[cfg(not(unix))] #[cfg(not(unix))]
return Err(exit.code().unwrap().into()); return Err(exit.code().unwrap().into());