diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2015-04-14 11:17:47 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2015-04-14 13:50:45 -0700 |
| commit | 5e073293064a227ebf454053c8aa35d7d8bdcf52 (patch) | |
| tree | c47ddec7819815ebf4385a7dcab6a7f52f204b8c /src/libstd/sys/windows/pipe2.rs | |
| parent | dabf0c6371d3b193664f58746fa27c1835a010f3 (diff) | |
std: Remove final usage of fds from Windows
This commit removes the last remnants of file descriptors from the Windows implementation of `std::sys` by using `CreatePipe` to create anonymous pipes instead of the `pipe` shim provided in msvcrt.
Diffstat (limited to 'src/libstd/sys/windows/pipe2.rs')
| -rw-r--r-- | src/libstd/sys/windows/pipe2.rs | 63 |
1 files changed, 16 insertions, 47 deletions
diff --git a/src/libstd/sys/windows/pipe2.rs b/src/libstd/sys/windows/pipe2.rs index ed41c959782..b441d8beedb 100644 --- a/src/libstd/sys/windows/pipe2.rs +++ b/src/libstd/sys/windows/pipe2.rs @@ -10,70 +10,39 @@ use prelude::v1::*; -use sys::handle; use io; -use libc::{self, c_int, HANDLE}; +use libc; +use sys::cvt; +use sys::c; +use sys::handle::Handle; //////////////////////////////////////////////////////////////////////////////// // Anonymous pipes //////////////////////////////////////////////////////////////////////////////// pub struct AnonPipe { - fd: c_int + inner: Handle, } pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> { - // Windows pipes work subtly differently than unix pipes, and their - // inheritance has to be handled in a different way that I do not - // fully understand. Here we explicitly make the pipe non-inheritable, - // which means to pass it to a subprocess they need to be duplicated - // first, as in std::run. - let mut fds = [0; 2]; - unsafe { - match libc::pipe(fds.as_mut_ptr(), 1024 as ::libc::c_uint, - (libc::O_BINARY | libc::O_NOINHERIT) as c_int) { - 0 => { - assert!(fds[0] != -1 && fds[0] != 0); - assert!(fds[1] != -1 && fds[1] != 0); - - Ok((AnonPipe::from_fd(fds[0]), AnonPipe::from_fd(fds[1]))) - } - _ => Err(io::Error::last_os_error()), - } - } + let mut reader = libc::INVALID_HANDLE_VALUE; + let mut writer = libc::INVALID_HANDLE_VALUE; + try!(cvt(unsafe { + c::CreatePipe(&mut reader, &mut writer, 0 as *mut _, 0) + })); + let reader = Handle::new(reader); + let writer = Handle::new(writer); + Ok((AnonPipe { inner: reader }, AnonPipe { inner: writer })) } impl AnonPipe { - pub fn from_fd(fd: libc::c_int) -> AnonPipe { - AnonPipe { fd: fd } - } - - pub fn raw(&self) -> HANDLE { - unsafe { libc::get_osfhandle(self.fd) as libc::HANDLE } - } + pub fn handle(&self) -> &Handle { &self.inner } pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { - handle::read(self.raw(), buf) + self.inner.read(buf) } pub fn write(&self, buf: &[u8]) -> io::Result<usize> { - handle::write(self.raw(), buf) - } -} - -impl Drop for AnonPipe { - fn drop(&mut self) { - // closing stdio file handles makes no sense, so never do it. Also, note - // that errors are ignored when closing a file descriptor. The reason - // for this is that if an error occurs we don't actually know if the - // file descriptor was closed or not, and if we retried (for something - // like EINTR), we might close another valid file descriptor (opened - // after we closed ours. - if self.fd > libc::STDERR_FILENO { - let n = unsafe { libc::close(self.fd) }; - if n != 0 { - println!("error {} when closing file descriptor {}", n, self.fd); - } - } + self.inner.write(buf) } } |
