From 10bdc1ffaef23584d77014c0afb17573c28325bc Mon Sep 17 00:00:00 2001 From: Etienne Cordonnier Date: Tue, 9 Dec 2025 13:43:37 +0100 Subject: [PATCH] nohup: use Command::exec() instead of libc::execvp() No need to use the unsafe `libc::execvp()`, the standard rust library provides the functionality via the safe function `Command::exec()`. Signed-off-by: Etienne Cordonnier --- src/uu/nohup/src/nohup.rs | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/uu/nohup/src/nohup.rs b/src/uu/nohup/src/nohup.rs index 0c596c162..28292ac41 100644 --- a/src/uu/nohup/src/nohup.rs +++ b/src/uu/nohup/src/nohup.rs @@ -3,17 +3,17 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore (ToDO) execvp SIGHUP cproc vprocmgr cstrs homeout +// spell-checker:ignore (ToDO) SIGHUP cproc vprocmgr homeout use clap::{Arg, ArgAction, Command}; -use libc::{SIG_IGN, SIGHUP}; -use libc::{c_char, dup2, execvp, signal}; +use libc::{SIG_IGN, SIGHUP, dup2, signal}; use std::env; -use std::ffi::CString; use std::fs::{File, OpenOptions}; -use std::io::{Error, IsTerminal}; +use std::io::{Error, ErrorKind, IsTerminal}; use std::os::unix::prelude::*; +use std::os::unix::process::CommandExt; use std::path::{Path, PathBuf}; +use std::process; use thiserror::Error; use uucore::display::Quotable; use uucore::error::{UError, UResult, set_exit_code}; @@ -68,17 +68,14 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { return Err(NohupError::CannotDetach.into()); } - let cstrs: Vec = matches - .get_many::(options::CMD) - .unwrap() - .map(|x| CString::new(x.as_bytes()).unwrap()) - .collect(); - let mut args: Vec<*const c_char> = cstrs.iter().map(|s| s.as_ptr()).collect(); - args.push(std::ptr::null()); + let mut cmd_iter = matches.get_many::(options::CMD).unwrap(); + let cmd = cmd_iter.next().unwrap(); + let args: Vec<&String> = cmd_iter.collect(); - let ret = unsafe { execvp(args[0], args.as_mut_ptr()) }; - match ret { - libc::ENOENT => set_exit_code(EXIT_ENOENT), + let err = process::Command::new(cmd).args(args).exec(); + + match err.kind() { + ErrorKind::NotFound => set_exit_code(EXIT_ENOENT), _ => set_exit_code(EXIT_CANNOT_INVOKE), } Ok(())