-use env::{split_paths};
-use ffi::{CStr, OsStr};
-use fmt;
-use fs::File;
-use io::{self, prelude::*, BufReader, Error, ErrorKind, SeekFrom};
+use crate::env::{self, split_paths};
+use crate::ffi::{CStr, OsStr};
+use crate::fmt;
+use crate::fs::File;
+use crate::io::{self, prelude::*, BufReader, Error, ErrorKind, SeekFrom};
+use crate::os::unix::ffi::OsStrExt;
+use crate::path::{Path, PathBuf};
+use crate::ptr;
+use crate::sys::ext::fs::MetadataExt;
+use crate::sys::ext::io::AsRawFd;
+use crate::sys::fd::FileDesc;
+use crate::sys::fs::{File as SysFile, OpenOptions};
+use crate::sys::os::{ENV_LOCK, environ};
+use crate::sys::pipe::{self, AnonPipe};
+use crate::sys::{cvt, syscall};
+use crate::sys_common::process::{CommandEnv, DefaultEnvKey};
+
use libc::{EXIT_SUCCESS, EXIT_FAILURE};
-use os::unix::ffi::OsStrExt;
-use path::{Path, PathBuf};
-use ptr;
-use sys::ext::fs::MetadataExt;
-use sys::ext::io::AsRawFd;
-use sys::fd::FileDesc;
-use sys::fs::{File as SysFile, OpenOptions};
-use sys::os::{ENV_LOCK, environ};
-use sys::pipe::{self, AnonPipe};
-use sys::{cvt, syscall};
-use sys_common::process::{CommandEnv, DefaultEnvKey};
////////////////////////////////////////////////////////////////////////////////
// Command
match cvt(syscall::clone(0))? {
0 => {
drop(input);
- let err = self.do_exec(theirs);
+ let Err(err) = self.do_exec(theirs);
let errno = err.raw_os_error().unwrap_or(syscall::EINVAL) as u32;
let bytes = [
(errno >> 24) as u8,
}
match self.setup_io(default, true) {
- Ok((_, theirs)) => unsafe { self.do_exec(theirs) },
+ Ok((_, theirs)) => unsafe {
+ let Err(e) = self.do_exec(theirs);
+ e
+ },
Err(e) => e,
}
}
// allocation). Instead we just close it manually. This will never
// have the drop glue anyway because this code never returns (the
// child will either exec() or invoke syscall::exit)
- unsafe fn do_exec(&mut self, stdio: ChildPipes) -> io::Error {
- macro_rules! t {
- ($e:expr) => (match $e {
- Ok(e) => e,
- Err(e) => return e,
- })
- }
-
+ unsafe fn do_exec(&mut self, stdio: ChildPipes) -> Result<!, io::Error> {
if let Some(fd) = stdio.stderr.fd() {
- t!(cvt(syscall::dup2(fd, 2, &[])));
- let mut flags = t!(cvt(syscall::fcntl(2, syscall::F_GETFD, 0)));
+ cvt(syscall::dup2(fd, 2, &[]))?;
+ let mut flags = cvt(syscall::fcntl(2, syscall::F_GETFD, 0))?;
flags &= ! syscall::O_CLOEXEC;
- t!(cvt(syscall::fcntl(2, syscall::F_SETFD, flags)));
+ cvt(syscall::fcntl(2, syscall::F_SETFD, flags))?;
}
if let Some(fd) = stdio.stdout.fd() {
- t!(cvt(syscall::dup2(fd, 1, &[])));
- let mut flags = t!(cvt(syscall::fcntl(1, syscall::F_GETFD, 0)));
+ cvt(syscall::dup2(fd, 1, &[]))?;
+ let mut flags = cvt(syscall::fcntl(1, syscall::F_GETFD, 0))?;
flags &= ! syscall::O_CLOEXEC;
- t!(cvt(syscall::fcntl(1, syscall::F_SETFD, flags)));
+ cvt(syscall::fcntl(1, syscall::F_SETFD, flags))?;
}
if let Some(fd) = stdio.stdin.fd() {
- t!(cvt(syscall::dup2(fd, 0, &[])));
- let mut flags = t!(cvt(syscall::fcntl(0, syscall::F_GETFD, 0)));
+ cvt(syscall::dup2(fd, 0, &[]))?;
+ let mut flags = cvt(syscall::fcntl(0, syscall::F_GETFD, 0))?;
flags &= ! syscall::O_CLOEXEC;
- t!(cvt(syscall::fcntl(0, syscall::F_SETFD, flags)));
+ cvt(syscall::fcntl(0, syscall::F_SETFD, flags))?;
}
if let Some(g) = self.gid {
- t!(cvt(syscall::setregid(g as usize, g as usize)));
+ cvt(syscall::setregid(g as usize, g as usize))?;
}
if let Some(u) = self.uid {
- t!(cvt(syscall::setreuid(u as usize, u as usize)));
+ cvt(syscall::setreuid(u as usize, u as usize))?;
}
if let Some(ref cwd) = self.cwd {
- t!(cvt(syscall::chdir(cwd)));
+ cvt(syscall::chdir(cwd))?;
}
for callback in self.closures.iter_mut() {
- t!(callback());
+ callback()?;
}
self.env.apply();
let program = if self.program.contains(':') || self.program.contains('/') {
Some(PathBuf::from(&self.program))
- } else if let Ok(path_env) = ::env::var("PATH") {
+ } else if let Ok(path_env) = env::var("PATH") {
let mut program = None;
for mut path in split_paths(&path_env) {
path.push(&self.program);
};
let mut file = if let Some(program) = program {
- t!(File::open(program.as_os_str()))
+ File::open(program.as_os_str())?
} else {
- return io::Error::from_raw_os_error(syscall::ENOENT);
+ return Err(io::Error::from_raw_os_error(syscall::ENOENT));
};
// Push all the arguments
let mut shebang = [0; 2];
let mut read = 0;
loop {
- match t!(reader.read(&mut shebang[read..])) {
+ match reader.read(&mut shebang[read..])? {
0 => break,
n => read += n,
}
// First of all, since we'll be passing another file to
// fexec(), we need to manually check that we have permission
// to execute this file:
- let uid = t!(cvt(syscall::getuid()));
- let gid = t!(cvt(syscall::getgid()));
- let meta = t!(file.metadata());
+ let uid = cvt(syscall::getuid())?;
+ let gid = cvt(syscall::getgid())?;
+ let meta = file.metadata()?;
let mode = if uid == meta.uid() as usize {
meta.mode() >> 3*2 & 0o7
meta.mode() & 0o7
};
if mode & 1 == 0 {
- return io::Error::from_raw_os_error(syscall::EPERM);
+ return Err(io::Error::from_raw_os_error(syscall::EPERM));
}
// Second of all, we need to actually read which interpreter it wants
let mut interpreter = Vec::new();
- t!(reader.read_until(b'\n', &mut interpreter));
+ reader.read_until(b'\n', &mut interpreter)?;
// Pop one trailing newline, if any
if interpreter.ends_with(&[b'\n']) {
interpreter.pop().unwrap();
};
if let Some(ref interpreter) = interpreter {
let path: &OsStr = OsStr::from_bytes(&interpreter);
- file = t!(File::open(path));
+ file = File::open(path)?;
args.push([interpreter.as_ptr() as usize, interpreter.len()]);
} else {
- t!(file.seek(SeekFrom::Start(0)));
+ file.seek(SeekFrom::Start(0))?;
}
args.push([self.program.as_ptr() as usize, self.program.len()]);
}
if let Err(err) = syscall::fexec(file.as_raw_fd(), &args, &vars) {
- io::Error::from_raw_os_error(err.errno as i32)
+ Err(io::Error::from_raw_os_error(err.errno as i32))
} else {
panic!("return from exec without err");
}
}
-
fn setup_io(&self, default: Stdio, needs_stdin: bool)
-> io::Result<(StdioPipes, ChildPipes)> {
let null = Stdio::Null;
}
impl fmt::Debug for Command {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self.program)?;
for arg in &self.args {
write!(f, " {:?}", arg)?;
}
impl fmt::Display for ExitStatus {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(code) = self.code() {
write!(f, "exit code: {}", code)
} else {