Skip to content

Commit

Permalink
updated os_pipe, with Windows support
Browse files Browse the repository at this point in the history
  • Loading branch information
oconnor663 committed Aug 17, 2016
1 parent 3dc4317 commit aac4dd3
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 28 deletions.
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ repository = "https://github.com/oconnor663/duct.rs"
license = "MIT"

[dependencies]
libc = ">=0.2.8"
os_pipe = ">=0.1.1"
crossbeam = ">=0.2.8"
os_pipe = ">=0.1.0"

[dev-dependencies]
tempfile = ">=2.1.1"
Expand Down
35 changes: 9 additions & 26 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
extern crate crossbeam;
extern crate os_pipe;

use os_pipe::PipePair;
use std::borrow::Borrow;
use std::collections::HashMap;
use std::ffi::{OsStr, OsString};
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::mem::forget;
use std::os::unix::io::{RawFd, FromRawFd, IntoRawFd};
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use std::process::Command;
use std::thread::JoinHandle;
use std::sync::Arc;

Expand Down Expand Up @@ -200,9 +197,9 @@ impl<'a> ExecutableExpression<'a> {
fn exec_argv<T: AsRef<OsStr>>(argv: &[T], context: IoContext) -> io::Result<Status> {
let mut command = Command::new(&argv[0]);
command.args(&argv[1..]);
command.stdin(stdio_from_file(context.stdin));
command.stdout(stdio_from_file(context.stdout));
command.stderr(stdio_from_file(context.stderr));
command.stdin(os_pipe::stdio_from_file(context.stdin));
command.stdout(os_pipe::stdio_from_file(context.stdout));
command.stderr(os_pipe::stdio_from_file(context.stderr));
command.current_dir(context.dir);
command.env_clear();
for (name, val) in context.env {
Expand Down Expand Up @@ -631,9 +628,9 @@ impl IoContext {
env.insert(name, val);
}
let context = IoContext {
stdin: try!(dup_fd(0)),
stdout: try!(dup_fd(1)),
stderr: try!(dup_fd(2)),
stdin: try!(os_pipe::dup_stdin()),
stdout: try!(os_pipe::dup_stdout()),
stderr: try!(os_pipe::dup_stderr()),
stdout_capture: stdout_capture,
stderr_capture: stderr_capture,
dir: try!(std::env::current_dir()),
Expand All @@ -658,7 +655,7 @@ impl IoContext {
type ReaderThread = JoinHandle<io::Result<Vec<u8>>>;

fn pipe_with_reader_thread() -> io::Result<(File, ReaderThread)> {
let PipePair { mut read, write } = try!(os_pipe::pipe());
let os_pipe::Pair { mut read, write } = try!(os_pipe::pipe());
let thread = std::thread::spawn(move || {
let mut output = Vec::new();
try!(read.read_to_end(&mut output));
Expand All @@ -672,28 +669,14 @@ type WriterThread = crossbeam::ScopedJoinHandle<io::Result<()>>;
fn pipe_with_writer_thread<'a>(input: &'a [u8],
scope: &crossbeam::Scope<'a>)
-> io::Result<(File, WriterThread)> {
let PipePair { read, mut write } = try!(os_pipe::pipe());
let os_pipe::Pair { read, mut write } = try!(os_pipe::pipe());
let thread = scope.spawn(move || {
try!(write.write_all(&input));
Ok(())
});
Ok((read, thread))
}

fn dup_fd(fd: RawFd) -> io::Result<File> {
// Running the destructor for this file will close the fd. We don't want that. (For example, it
// could be the whole process's stdout.) So we need to make sure we always forget() the file
// object, even in the case where try_clone() returns an error.
let file = unsafe { File::from_raw_fd(fd) };
let result = file.try_clone();
forget(file);
result
}

fn stdio_from_file(file: File) -> Stdio {
unsafe { Stdio::from_raw_fd(file.into_raw_fd()) }
}

#[cfg(test)]
mod test {
extern crate tempfile;
Expand Down

0 comments on commit aac4dd3

Please sign in to comment.