Skip to content

Commit

Permalink
posix/sh: rework builtin/function execution for redirection
Browse files Browse the repository at this point in the history
While redirection is not yet supported, the framework is now in
place.  Due to creating custom UtilSetups for builtins/functions,
UtilSetup/UtilData needed to be reworked to use borrowed mutable
pointers rather than RefCell internally, which necessitated changes
in other utilities as well.  On the plus side, we no longer need
ensure the borrow checker's constraints are satisfied at runtime,
which should (hopefully) improve execution time slightly and
reduce the risk of an unintended panic.
  • Loading branch information
Arcterus committed Jun 28, 2018
1 parent ea2628e commit 1b32bde
Show file tree
Hide file tree
Showing 19 changed files with 362 additions and 341 deletions.
76 changes: 38 additions & 38 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ cat = []
chmod = ["regex", "walkdir", "uucore"]
head = []
init = ["fnv", "nix"]
sh = ["either", "fnv", "nom", "globset", "rustyline"]
sh = ["either", "fnv", "nix", "nom", "globset", "rustyline"]
sleep = ["uucore"]
posix = [
"cat",
Expand Down
2 changes: 1 addition & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ fn main() {
where
S: UtilSetup,
{{
let mut stdout = setup.output();
let stdout = setup.output();
let mut stdout = stdout.lock_writer()?;"
).unwrap();
for util in &utils {
Expand Down
8 changes: 5 additions & 3 deletions src/gnu/base32/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,17 +96,19 @@ where
format: format,
};

let mut output = setup.output();
let output = output.lock_writer()?;
match matches.value_of_os("FILE") {
Some(filename) if filename != OsStr::new("-") => {
let path = util::actual_path(&setup.current_dir(), filename);
let file = File::open(path)?;

let mut output = setup.output();
let output = output.lock_writer()?;
handle_data(output, BufReader::new(file), options)
}
_ => {
let mut input = setup.input();
let (mut input, mut output, _) = setup.stdio();
let input = input.lock_reader()?;
let output = output.lock_writer()?;
handle_data(output, input, options)
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/gnu/yes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ pub fn run<S>(setup: &mut S, bytes: &[u8]) -> Result<()>
where
S: UtilSetup,
{
let mut stdout = setup.output();
let stdout = setup.output();
let mut stdout = stdout.lock_writer()?;
loop {
stdout.write_all(bytes)?;
Expand Down
66 changes: 33 additions & 33 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,32 +73,32 @@ mod util;
// contains all the "mod"s which allow us to use the utils
include!(concat!(env!("OUT_DIR"), "/utils.rs"));

pub struct UtilData<I, O, E, T>
pub struct UtilData<'b, 'c, 'd, I, O, E, T>
where
I: for<'a> UtilRead<'a>,
O: for<'a> UtilWrite<'a>,
E: for<'a> UtilWrite<'a>,
I: for<'a> UtilRead<'a> + 'b,
O: for<'a> UtilWrite<'a> + 'c,
E: for<'a> UtilWrite<'a> + 'd,
T: Iterator<Item = (OsString, OsString)>,
{
pub stdin: RefCell<I>,
pub stdout: RefCell<O>,
pub stderr: RefCell<E>,
pub stdin: &'b mut I,
pub stdout: &'c mut O,
pub stderr: &'d mut E,
pub env: T,
pub current_dir: Option<PathBuf>,
}

impl<I, O, E, T> UtilData<I, O, E, T>
impl<'b, 'c, 'd, I, O, E, T> UtilData<'b, 'c, 'd, I, O, E, T>
where
I: for<'a> UtilRead<'a>,
O: for<'a> UtilWrite<'a>,
E: for<'a> UtilWrite<'a>,
T: Iterator<Item = (OsString, OsString)>,
{
pub fn new(stdin: I, stdout: O, stderr: E, env: T, current_dir: Option<PathBuf>) -> Self {
pub fn new(stdin: &'b mut I, stdout: &'c mut O, stderr: &'d mut E, env: T, current_dir: Option<PathBuf>) -> Self {
Self {
stdin: RefCell::new(stdin),
stdout: RefCell::new(stdout),
stderr: RefCell::new(stderr),
stdin: stdin,
stdout: stdout,
stderr: stderr,
env: env,
current_dir: current_dir,
}
Expand All @@ -111,24 +111,24 @@ pub trait UtilSetup {
type Error: for<'a> UtilWrite<'a>;
type Env: Iterator<Item = (OsString, OsString)>;

fn input(&self) -> RefMut<Self::Input>;
fn output(&self) -> RefMut<Self::Output>;
fn error(&self) -> RefMut<Self::Error>;
fn input<'a, 'b: 'a>(&'b mut self) -> &'a mut Self::Input;
fn output<'a, 'b: 'a>(&'b mut self) -> &'a mut Self::Output;
fn error<'a, 'b: 'a>(&'b mut self) -> &'a mut Self::Error;

fn stdio(
&self,
fn stdio<'a, 'b: 'a>(
&'b mut self,
) -> (
RefMut<Self::Input>,
RefMut<Self::Output>,
RefMut<Self::Error>,
&'a mut Self::Input,
&'a mut Self::Output,
&'a mut Self::Error,
);

fn env(&mut self) -> &mut Self::Env;

fn current_dir(&self) -> Option<&Path>;
}

impl<I, O, E, T> UtilSetup for UtilData<I, O, E, T>
impl<'b, 'c, 'd, I, O, E, T> UtilSetup for UtilData<'b, 'c, 'd, I, O, E, T>
where
I: for<'a> UtilRead<'a>,
O: for<'a> UtilWrite<'a>,
Expand All @@ -140,26 +140,26 @@ where
type Error = E;
type Env = T;

fn input(&self) -> RefMut<Self::Input> {
self.stdin.borrow_mut()
fn input<'a, 'e: 'a>(&'e mut self) -> &'a mut Self::Input {
self.stdin
}

fn output(&self) -> RefMut<Self::Output> {
self.stdout.borrow_mut()
fn output<'a, 'e: 'a>(&'e mut self) -> &'a mut Self::Output {
self.stdout
}

fn error(&self) -> RefMut<Self::Error> {
self.stderr.borrow_mut()
fn error<'a, 'e: 'a>(&'e mut self) -> &'a mut Self::Error {
self.stderr
}

fn stdio(
&self,
fn stdio<'a, 'e: 'a>(
&'e mut self,
) -> (
RefMut<Self::Input>,
RefMut<Self::Output>,
RefMut<Self::Error>,
&'a mut Self::Input,
&'a mut Self::Output,
&'a mut Self::Error,
) {
(self.input(), self.output(), self.error())
(self.stdin, self.stdout, self.stderr)
}

fn env(&mut self) -> &mut Self::Env {
Expand Down
6 changes: 3 additions & 3 deletions src/lsb/tar/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,9 @@ where
Self::list_contents_helper(&mut *self.setup.output(), &mut self.options.values, archive)
}
_ => {
let mut input = self.setup.input();
let archive = tar::Archive::new(&mut *input);
Self::list_contents_helper(&mut *self.setup.output(), &mut self.options.values, archive)
let (input, output, _) = self.setup.stdio();
let archive = tar::Archive::new(input);
Self::list_contents_helper(output, &mut self.options.values, archive)
}
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ use std::process;

// this is just a thin wrapper around the library
fn main() {
let stdout = io::stdout();
let stdin = io::stdin();
let stderr = io::stderr();
let mut stdout = io::stdout();
let mut stdin = io::stdin();
let mut stderr = io::stderr();

let mut setup = UtilData::new(stdin, stdout, stderr, env::vars_os(), None);
let mut setup = UtilData::new(&mut stdin, &mut stdout, &mut stderr, env::vars_os(), None);

if let Err(f) = mesabox::execute(&mut setup, &mut env::args_os()) {
if let Some(ref err) = f.err {
Expand All @@ -32,8 +32,8 @@ fn main() {
}

if !skip {
let _ = writeln!(setup.stderr.get_mut(), "{}", f);
let _ = setup.stderr.get_mut().flush();
let _ = writeln!(setup.stderr, "{}", f);
let _ = setup.stderr.flush();
}
}
process::exit(f.exitcode);
Expand Down
4 changes: 2 additions & 2 deletions src/networking/ping/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ where

let should_stop = AtomicBool::new(false);
{
let mut stdout_ref = setup.output();
let stdout_ref = setup.output();
crossbeam::scope(|scope| {
let should_stop_ref = &should_stop;
let stdout_ref = &mut *stdout_ref;
Expand Down Expand Up @@ -450,7 +450,7 @@ where
set.add(Signal::SIGINT);
set.thread_set_mask()?;

let mut stdout = setup.output();
let stdout = setup.output();
let mut stdout = stdout.lock_writer()?;

writeln!(stdout, "\n--- {} ping statistics ---", hostname)?;
Expand Down
2 changes: 1 addition & 1 deletion src/posix/cat/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ where
let interactive = is_tty(setup.input().raw_fd());
// XXX: should current_dir() just return Option<Rc<Path>> or something similar to avoid the cloning?
let curdir = setup.current_dir().map(|p| p.to_path_buf());
let (mut input, mut output, mut error) = setup.stdio();
let (input, output, error) = setup.stdio();
let stdin = input.lock_reader()?;
let stdout = output.lock_writer()?;
let stderr = error.lock_writer()?;
Expand Down
10 changes: 5 additions & 5 deletions src/posix/chmod/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ use std::ffi::{OsStr, OsString};
use std::fs;
use std::io::{self, Write};
use std::os::unix::fs::{MetadataExt, PermissionsExt};
use std::path::Path;
use std::path::{Path, PathBuf};
use std::result::Result as StdResult;
use walkdir::WalkDir;
use uucore::mode;
Expand Down Expand Up @@ -140,8 +140,8 @@ where
None => None,
};

let mut stdout = setup.output();
let mut stderr = setup.error();
let current_dir = setup.current_dir().map(|p| p.to_owned());
let (_, stdout, stderr) = setup.stdio();
let mut chmoder = Chmoder {
verbosity: verbosity,
preserve_root: preserve_root,
Expand All @@ -150,7 +150,7 @@ where
cmode: matches.value_of("MODE"),
stdout: stdout.lock_writer()?,
stderr: stderr.lock_writer()?,
current_dir: setup.current_dir(),
current_dir: current_dir,
};

let exitcode = chmoder.chmod(matches.values_of_os("FILES").unwrap())?;
Expand Down Expand Up @@ -199,7 +199,7 @@ where
cmode: Option<&'a str>,
stdout: O,
stderr: E,
current_dir: Option<&'a Path>,
current_dir: Option<PathBuf>,
}

impl<'a, O, E> Chmoder<'a, O, E>
Expand Down
13 changes: 7 additions & 6 deletions src/posix/head/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,13 @@ where
previous_printed: false,
};

let mut output = setup.output();
let current_dir = setup.current_dir().map(|p| p.to_owned());
let (input, output, error) = setup.stdio();

let mut output = output.lock_writer()?;
if matches.is_present("FILES") {
let mut result = Ok(());
let mut err_stream = setup.error();
let mut err_stream = err_stream.lock_writer()?;
let mut err_stream = error.lock_writer()?;

let file_count = matches.occurrences_of("FILES");

Expand All @@ -137,9 +138,9 @@ where
};
let res = if file == OsStr::new("-") {
let filename = filename.map(|_| OsStr::new("standard input"));
handle_stdin(&mut output, &mut *setup.input(), filename, &mut options)
handle_stdin(&mut output, input, filename, &mut options)
} else {
let path = util::actual_path(&setup.current_dir(), file);
let path = util::actual_path(&current_dir, file);
handle_file(&mut output, &path, filename, &mut options)
};

Expand All @@ -157,7 +158,7 @@ where
} else {
None
};
handle_stdin(output, &mut *setup.input(), filename, &mut options)
handle_stdin(output, input, filename, &mut options)
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/posix/init/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ where
});
}

let (mut stdin, mut stdout, mut stderr) = setup.stdio();
let (stdin, stdout, stderr) = setup.stdio();
let mut stdin = stdin.lock_reader()?;
let mut stdout = stdout.lock_writer()?;
let mut stderr = stderr.lock_writer()?;
Expand Down
Loading

0 comments on commit 1b32bde

Please sign in to comment.