Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions src/uu/chroot/src/chroot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
// TODO: refactor the args and command matching
// See: https://github.com/uutils/coreutils/pull/2365#discussion_r647849967
let command: Vec<&str> = match commands.len() {
1 => {
0 => {
let shell: &str = match user_shell {
Err(_) => default_shell,
Ok(ref s) => s.as_ref(),
Expand All @@ -77,12 +77,28 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
_ => commands,
};

assert!(!command.is_empty());
let chroot_command = command[0];
let chroot_args = &command[1..];

// NOTE: Tests can only trigger code beyond this point if they're invoked with root permissions
set_context(newroot, &matches);

let pstatus = Command::new(command[0])
.args(&command[1..])
let pstatus = Command::new(chroot_command)
.args(chroot_args)
.status()
.unwrap_or_else(|e| crash!(1, "Cannot exec: {}", e));
.unwrap_or_else(|e| {
// TODO: Exit status:
// 125 if chroot itself fails
// 126 if command is found but cannot be invoked
// 127 if command cannot be found
crash!(
1,
"failed to run command {}: {}",
command[0].to_string().quote(),
e
)
});

if pstatus.success() {
0
Expand Down
24 changes: 24 additions & 0 deletions tests/by-util/test_chroot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ fn test_missing_operand() {

#[test]
fn test_enter_chroot_fails() {
// NOTE: since #2689 this test also ensures that we don't regress #2687
let (at, mut ucmd) = at_and_ucmd!();

at.mkdir("jail");
Expand Down Expand Up @@ -89,3 +90,26 @@ fn test_preference_of_userspec() {
println!("result.stdout = {}", result.stdout_str());
println!("result.stderr = {}", result.stderr_str());
}

#[test]
fn test_default_shell() {
// NOTE: This test intends to trigger code which can only be reached with root permissions.
let ts = TestScenario::new(util_name!());
let at = &ts.fixtures;

let dir = "CHROOT_DIR";
at.mkdir(dir);

let shell = std::env::var("SHELL").unwrap_or_else(|_| "/bin/sh".to_string());
let _expected = format!(
"chroot: failed to run command '{}': No such file or directory",
shell
);

// TODO: [2021-09; jhscheer] uncomment if/when #2692 gets merged
// if let Ok(result) = run_ucmd_as_root(&ts, &[dir]) {
// result.stderr_contains(expected);
// } else {
// print!("TEST SKIPPED");
// }
}