From 5053c7b66f6562fe35ace5ab5b82b5dab981dfac Mon Sep 17 00:00:00 2001 From: oech3 <79379754+oech3@users.noreply.github.com> Date: Mon, 6 Jul 2026 16:49:22 +0900 Subject: [PATCH] chroot: avoid unwrap-like operation --- src/uu/chroot/src/chroot.rs | 40 +++++++++++++------------------------ 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/src/uu/chroot/src/chroot.rs b/src/uu/chroot/src/chroot.rs index 985d8deb14e..129fad6bc7f 100644 --- a/src/uu/chroot/src/chroot.rs +++ b/src/uu/chroot/src/chroot.rs @@ -8,7 +8,7 @@ mod error; use crate::error::ChrootError; use clap::{Arg, ArgAction, Command}; -use std::ffi::OsStr; +use std::ffi::OsString; use std::io::{Error, ErrorKind}; use std::os::unix::process::CommandExt; use std::path::{Path, PathBuf}; @@ -158,10 +158,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let matches = uucore::clap_localization::handle_clap_result_with_exit_code(uu_app(), args, 125)?; - let default_shell: &'static OsStr = OsStr::new("/bin/sh"); - let default_option: &'static OsStr = OsStr::new("-i"); - let user_shell = std::env::var_os("SHELL"); - let options = Options::from(&matches)?; // We are resolving the path in case it is a symlink or /. or /../ @@ -188,35 +184,27 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { return Err(ChrootError::NoSuchDirectory(options.newroot).into()); } - let commands: Vec<&OsStr> = matches - .get_many::(options::COMMAND) - .map_or_else(Vec::new, |v| v.map(OsStr::new).collect()); - - // TODO: refactor the args and command matching - // See: https://github.com/uutils/coreutils/pull/2365#discussion_r647849967 - let command = if commands.is_empty() { - vec![ - user_shell.as_deref().unwrap_or(default_shell), - default_option, - ] - } else { - commands + let mut cmd_iter = matches + .get_many::(options::COMMAND) + .into_iter() + .flatten(); + let (chroot_command, args) = match cmd_iter.next() { + Some(c) => (c.clone(), cmd_iter.cloned().collect::>()), + None => ( + std::env::var_os("SHELL").unwrap_or_else(|| "/bin/sh".into()), + vec!["-i".into()], + ), }; - assert!(!command.is_empty()); - let chroot_command = command[0]; - // NOTE: Tests can only trigger code beyond this point if they're invoked with root permissions set_context(&options)?; - let err = process::Command::new(chroot_command) - .args(&command[1..]) - .exec(); + let err = process::Command::new(&chroot_command).args(&args).exec(); Err(if err.kind() == ErrorKind::NotFound { - ChrootError::CommandNotFound(chroot_command.to_owned(), err) + ChrootError::CommandNotFound(chroot_command, err) } else { - ChrootError::CommandFailed(chroot_command.to_owned(), err) + ChrootError::CommandFailed(chroot_command, err) } .into()) }