Rollup merge of #60581 - hellow554:fix_60580, r=alexcrichton

convert custom try macro to `?`

resolves #60580

r? @frewsxcv
This commit is contained in:
Mazdak Farrokhzad 2019-05-22 03:47:31 +02:00 committed by GitHub
commit d69ef04af5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 57 deletions

View File

@ -150,7 +150,7 @@ impl Command {
match cvt(syscall::clone(0))? { match cvt(syscall::clone(0))? {
0 => { 0 => {
drop(input); 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 errno = err.raw_os_error().unwrap_or(syscall::EINVAL) as u32;
let bytes = [ let bytes = [
(errno >> 24) as u8, (errno >> 24) as u8,
@ -218,7 +218,10 @@ impl Command {
} }
match self.setup_io(default, true) { 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, Err(e) => e,
} }
} }
@ -253,45 +256,38 @@ impl Command {
// allocation). Instead we just close it manually. This will never // allocation). Instead we just close it manually. This will never
// have the drop glue anyway because this code never returns (the // have the drop glue anyway because this code never returns (the
// child will either exec() or invoke syscall::exit) // child will either exec() or invoke syscall::exit)
unsafe fn do_exec(&mut self, stdio: ChildPipes) -> io::Error { unsafe fn do_exec(&mut self, stdio: ChildPipes) -> Result<!, io::Error> {
macro_rules! t {
($e:expr) => (match $e {
Ok(e) => e,
Err(e) => return e,
})
}
if let Some(fd) = stdio.stderr.fd() { if let Some(fd) = stdio.stderr.fd() {
t!(cvt(syscall::dup2(fd, 2, &[]))); cvt(syscall::dup2(fd, 2, &[]))?;
let mut flags = t!(cvt(syscall::fcntl(2, syscall::F_GETFD, 0))); let mut flags = cvt(syscall::fcntl(2, syscall::F_GETFD, 0))?;
flags &= ! syscall::O_CLOEXEC; 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() { if let Some(fd) = stdio.stdout.fd() {
t!(cvt(syscall::dup2(fd, 1, &[]))); cvt(syscall::dup2(fd, 1, &[]))?;
let mut flags = t!(cvt(syscall::fcntl(1, syscall::F_GETFD, 0))); let mut flags = cvt(syscall::fcntl(1, syscall::F_GETFD, 0))?;
flags &= ! syscall::O_CLOEXEC; 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() { if let Some(fd) = stdio.stdin.fd() {
t!(cvt(syscall::dup2(fd, 0, &[]))); cvt(syscall::dup2(fd, 0, &[]))?;
let mut flags = t!(cvt(syscall::fcntl(0, syscall::F_GETFD, 0))); let mut flags = cvt(syscall::fcntl(0, syscall::F_GETFD, 0))?;
flags &= ! syscall::O_CLOEXEC; 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 { 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 { 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 { if let Some(ref cwd) = self.cwd {
t!(cvt(syscall::chdir(cwd))); cvt(syscall::chdir(cwd))?;
} }
for callback in self.closures.iter_mut() { for callback in self.closures.iter_mut() {
t!(callback()); callback()?;
} }
self.env.apply(); self.env.apply();
@ -313,9 +309,9 @@ impl Command {
}; };
let mut file = if let Some(program) = program { let mut file = if let Some(program) = program {
t!(File::open(program.as_os_str())) File::open(program.as_os_str())?
} else { } else {
return io::Error::from_raw_os_error(syscall::ENOENT); return Err(io::Error::from_raw_os_error(syscall::ENOENT));
}; };
// Push all the arguments // Push all the arguments
@ -327,7 +323,7 @@ impl Command {
let mut shebang = [0; 2]; let mut shebang = [0; 2];
let mut read = 0; let mut read = 0;
loop { loop {
match t!(reader.read(&mut shebang[read..])) { match reader.read(&mut shebang[read..])? {
0 => break, 0 => break,
n => read += n, n => read += n,
} }
@ -338,9 +334,9 @@ impl Command {
// First of all, since we'll be passing another file to // First of all, since we'll be passing another file to
// fexec(), we need to manually check that we have permission // fexec(), we need to manually check that we have permission
// to execute this file: // to execute this file:
let uid = t!(cvt(syscall::getuid())); let uid = cvt(syscall::getuid())?;
let gid = t!(cvt(syscall::getgid())); let gid = cvt(syscall::getgid())?;
let meta = t!(file.metadata()); let meta = file.metadata()?;
let mode = if uid == meta.uid() as usize { let mode = if uid == meta.uid() as usize {
meta.mode() >> 3*2 & 0o7 meta.mode() >> 3*2 & 0o7
@ -350,12 +346,12 @@ impl Command {
meta.mode() & 0o7 meta.mode() & 0o7
}; };
if mode & 1 == 0 { 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 // Second of all, we need to actually read which interpreter it wants
let mut interpreter = Vec::new(); 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 // Pop one trailing newline, if any
if interpreter.ends_with(&[b'\n']) { if interpreter.ends_with(&[b'\n']) {
interpreter.pop().unwrap(); interpreter.pop().unwrap();
@ -373,11 +369,11 @@ impl Command {
}; };
if let Some(ref interpreter) = interpreter { if let Some(ref interpreter) = interpreter {
let path: &OsStr = OsStr::from_bytes(&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()]); args.push([interpreter.as_ptr() as usize, interpreter.len()]);
} else { } else {
t!(file.seek(SeekFrom::Start(0))); file.seek(SeekFrom::Start(0))?;
} }
args.push([self.program.as_ptr() as usize, self.program.len()]); args.push([self.program.as_ptr() as usize, self.program.len()]);
@ -396,13 +392,12 @@ impl Command {
} }
if let Err(err) = syscall::fexec(file.as_raw_fd(), &args, &vars) { 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 { } else {
panic!("return from exec without err"); panic!("return from exec without err");
} }
} }
fn setup_io(&self, default: Stdio, needs_stdin: bool) fn setup_io(&self, default: Stdio, needs_stdin: bool)
-> io::Result<(StdioPipes, ChildPipes)> { -> io::Result<(StdioPipes, ChildPipes)> {
let null = Stdio::Null; let null = Stdio::Null;

View File

@ -47,7 +47,7 @@ impl Command {
match result { match result {
0 => { 0 => {
drop(input); drop(input);
let err = self.do_exec(theirs, envp.as_ref()); let Err(err) = self.do_exec(theirs, envp.as_ref());
let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32; let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32;
let bytes = [ let bytes = [
(errno >> 24) as u8, (errno >> 24) as u8,
@ -123,7 +123,8 @@ impl Command {
// environment lock before we try to exec. // environment lock before we try to exec.
let _lock = sys::os::env_lock(); let _lock = sys::os::env_lock();
self.do_exec(theirs, envp.as_ref()) let Err(e) = self.do_exec(theirs, envp.as_ref());
e
} }
} }
Err(e) => e, Err(e) => e,
@ -164,29 +165,22 @@ impl Command {
&mut self, &mut self,
stdio: ChildPipes, stdio: ChildPipes,
maybe_envp: Option<&CStringArray> maybe_envp: Option<&CStringArray>
) -> io::Error { ) -> Result<!, io::Error> {
use crate::sys::{self, cvt_r}; use crate::sys::{self, cvt_r};
macro_rules! t {
($e:expr) => (match $e {
Ok(e) => e,
Err(e) => return e,
})
}
if let Some(fd) = stdio.stdin.fd() { if let Some(fd) = stdio.stdin.fd() {
t!(cvt_r(|| libc::dup2(fd, libc::STDIN_FILENO))); cvt_r(|| libc::dup2(fd, libc::STDIN_FILENO))?;
} }
if let Some(fd) = stdio.stdout.fd() { if let Some(fd) = stdio.stdout.fd() {
t!(cvt_r(|| libc::dup2(fd, libc::STDOUT_FILENO))); cvt_r(|| libc::dup2(fd, libc::STDOUT_FILENO))?;
} }
if let Some(fd) = stdio.stderr.fd() { if let Some(fd) = stdio.stderr.fd() {
t!(cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO))); cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO))?;
} }
if cfg!(not(any(target_os = "l4re"))) { if cfg!(not(any(target_os = "l4re"))) {
if let Some(u) = self.get_gid() { if let Some(u) = self.get_gid() {
t!(cvt(libc::setgid(u as gid_t))); cvt(libc::setgid(u as gid_t))?;
} }
if let Some(u) = self.get_uid() { if let Some(u) = self.get_uid() {
// When dropping privileges from root, the `setgroups` call // When dropping privileges from root, the `setgroups` call
@ -198,11 +192,11 @@ impl Command {
// privilege dropping function. // privilege dropping function.
let _ = libc::setgroups(0, ptr::null()); let _ = libc::setgroups(0, ptr::null());
t!(cvt(libc::setuid(u as uid_t))); cvt(libc::setuid(u as uid_t))?;
} }
} }
if let Some(ref cwd) = *self.get_cwd() { if let Some(ref cwd) = *self.get_cwd() {
t!(cvt(libc::chdir(cwd.as_ptr()))); cvt(libc::chdir(cwd.as_ptr()))?;
} }
// emscripten has no signal support. // emscripten has no signal support.
@ -225,18 +219,18 @@ impl Command {
0, 0,
mem::size_of::<libc::sigset_t>()); mem::size_of::<libc::sigset_t>());
} else { } else {
t!(cvt(libc::sigemptyset(&mut set))); cvt(libc::sigemptyset(&mut set))?;
} }
t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set, cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set,
ptr::null_mut()))); ptr::null_mut()))?;
let ret = sys::signal(libc::SIGPIPE, libc::SIG_DFL); let ret = sys::signal(libc::SIGPIPE, libc::SIG_DFL);
if ret == libc::SIG_ERR { if ret == libc::SIG_ERR {
return io::Error::last_os_error() return Err(io::Error::last_os_error())
} }
} }
for callback in self.get_closures().iter_mut() { for callback in self.get_closures().iter_mut() {
t!(callback()); callback()?;
} }
// Although we're performing an exec here we may also return with an // Although we're performing an exec here we may also return with an
@ -261,7 +255,7 @@ impl Command {
} }
libc::execvp(self.get_argv()[0], self.get_argv().as_ptr()); libc::execvp(self.get_argv()[0], self.get_argv().as_ptr());
io::Error::last_os_error() Err(io::Error::last_os_error())
} }
#[cfg(not(any(target_os = "macos", target_os = "freebsd", #[cfg(not(any(target_os = "macos", target_os = "freebsd",