From b422097b230ff2c6303a2f4eaf2450a031ba6e04 Mon Sep 17 00:00:00 2001 From: Isabelle Knott <isabelle@blackle-mori.com> Date: Thu, 4 Jan 2018 00:21:41 -0500 Subject: [PATCH] Call execve from fork_and_exec in sys/redox.rs so they can share code --- src/lib/sys/redox.rs | 103 ++++++++++++------------------------------- 1 file changed, 29 insertions(+), 74 deletions(-) diff --git a/src/lib/sys/redox.rs b/src/lib/sys/redox.rs index 95b652fe..7d73f68d 100644 --- a/src/lib/sys/redox.rs +++ b/src/lib/sys/redox.rs @@ -93,91 +93,46 @@ pub(crate) fn fork_and_exec<F: Fn()>( clear_env: bool, before_exec: F ) -> io::Result<u32> { - // Construct a valid set of arguments to pass to execve. Ensure - // that the program is the first argument. - let mut cvt_args: Vec<[usize; 2]> = Vec::new(); - cvt_args.push([prog.as_ptr() as usize, prog.len()]); - for arg in args { - cvt_args.push([arg.as_ptr() as usize, arg.len()]); - } - - // Get the PathBuf of the program if it exists. - let prog = if prog.contains(':') || prog.contains('/') { - // This is a fully specified scheme or path to an - // executable. - Some(PathBuf::from(prog)) - } else if let Ok(paths) = env::var("PATH") { - // This is not a fully specified scheme or path. - // Iterate through the possible paths in the - // env var PATH that this executable may be found - // in and return the first one found. - env::split_paths(&paths) - .filter_map(|mut path| { - path.push(prog); - if path.exists() { - Some(path) - } else { - None + unsafe { + match fork()? { + 0 => { + if let Some(stdin) = stdin { + let _ = dup2(stdin, STDIN_FILENO); + let _ = close(stdin); } - }) - .next() - } else { - None - }; - - // If clear_env set, clear the env. - if clear_env { - for (key, _) in env::vars() { - env::remove_var(key); - } - } - - if let Some(prog) = prog { - unsafe { - match fork()? { - 0 => { - if let Some(stdin) = stdin { - let _ = dup2(stdin, STDIN_FILENO); - let _ = close(stdin); - } - if let Some(stdout) = stdout { - let _ = dup2(stdout, STDOUT_FILENO); - let _ = close(stdout); - } + if let Some(stdout) = stdout { + let _ = dup2(stdout, STDOUT_FILENO); + let _ = close(stdout); + } - if let Some(stderr) = stderr { - let _ = dup2(stderr, STDERR_FILENO); - let _ = close(stderr); - } + if let Some(stderr) = stderr { + let _ = dup2(stderr, STDERR_FILENO); + let _ = close(stderr); + } - before_exec(); + before_exec(); - let error = syscall::execve(prog.as_os_str().as_bytes(), &cvt_args); - let error = io::Error::from_raw_os_error(error.err().unwrap().errno); - eprintln!("ion: command exec: {}", error); - fork_exit(1); + let error = execve(prog, args, clear_env); + eprintln!("ion: command exec: {}", error); + fork_exit(1); + } + pid => { + if let Some(stdin) = stdin { + let _ = close(stdin); } - pid => { - if let Some(stdin) = stdin { - let _ = close(stdin); - } - if let Some(stdout) = stdout { - let _ = close(stdout); - } - - if let Some(stderr) = stderr { - let _ = close(stderr); - } + if let Some(stdout) = stdout { + let _ = close(stdout); + } - Ok(pid) + if let Some(stderr) = stderr { + let _ = close(stderr); } + + Ok(pid) } } - } else { - // The binary was not found. - Err(io::Error::from_raw_os_error(syscall::ENOENT)) } } -- GitLab