|
10 | 10 |
|
11 | 11 | use prelude::v1::*;
|
12 | 12 |
|
13 |
| -use sys::handle; |
14 | 13 | use io;
|
15 |
| -use libc::{self, c_int, HANDLE}; |
| 14 | +use libc; |
| 15 | +use sys::cvt; |
| 16 | +use sys::c; |
| 17 | +use sys::handle::Handle; |
16 | 18 |
|
17 | 19 | ////////////////////////////////////////////////////////////////////////////////
|
18 | 20 | // Anonymous pipes
|
19 | 21 | ////////////////////////////////////////////////////////////////////////////////
|
20 | 22 |
|
21 | 23 | pub struct AnonPipe {
|
22 |
| - fd: c_int |
| 24 | + inner: Handle, |
23 | 25 | }
|
24 | 26 |
|
25 | 27 | pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
|
26 |
| - // Windows pipes work subtly differently than unix pipes, and their |
27 |
| - // inheritance has to be handled in a different way that I do not |
28 |
| - // fully understand. Here we explicitly make the pipe non-inheritable, |
29 |
| - // which means to pass it to a subprocess they need to be duplicated |
30 |
| - // first, as in std::run. |
31 |
| - let mut fds = [0; 2]; |
32 |
| - unsafe { |
33 |
| - match libc::pipe(fds.as_mut_ptr(), 1024 as ::libc::c_uint, |
34 |
| - (libc::O_BINARY | libc::O_NOINHERIT) as c_int) { |
35 |
| - 0 => { |
36 |
| - assert!(fds[0] != -1 && fds[0] != 0); |
37 |
| - assert!(fds[1] != -1 && fds[1] != 0); |
38 |
| - |
39 |
| - Ok((AnonPipe::from_fd(fds[0]), AnonPipe::from_fd(fds[1]))) |
40 |
| - } |
41 |
| - _ => Err(io::Error::last_os_error()), |
42 |
| - } |
43 |
| - } |
| 28 | + let mut reader = libc::INVALID_HANDLE_VALUE; |
| 29 | + let mut writer = libc::INVALID_HANDLE_VALUE; |
| 30 | + try!(cvt(unsafe { |
| 31 | + c::CreatePipe(&mut reader, &mut writer, 0 as *mut _, 0) |
| 32 | + })); |
| 33 | + let reader = Handle::new(reader); |
| 34 | + let writer = Handle::new(writer); |
| 35 | + Ok((AnonPipe { inner: reader }, AnonPipe { inner: writer })) |
44 | 36 | }
|
45 | 37 |
|
46 | 38 | impl AnonPipe {
|
47 |
| - pub fn from_fd(fd: libc::c_int) -> AnonPipe { |
48 |
| - AnonPipe { fd: fd } |
49 |
| - } |
50 |
| - |
51 |
| - pub fn raw(&self) -> HANDLE { |
52 |
| - unsafe { libc::get_osfhandle(self.fd) as libc::HANDLE } |
53 |
| - } |
| 39 | + pub fn handle(&self) -> &Handle { &self.inner } |
54 | 40 |
|
55 | 41 | pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
56 |
| - handle::read(self.raw(), buf) |
| 42 | + self.inner.read(buf) |
57 | 43 | }
|
58 | 44 |
|
59 | 45 | pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
60 |
| - handle::write(self.raw(), buf) |
61 |
| - } |
62 |
| -} |
63 |
| - |
64 |
| -impl Drop for AnonPipe { |
65 |
| - fn drop(&mut self) { |
66 |
| - // closing stdio file handles makes no sense, so never do it. Also, note |
67 |
| - // that errors are ignored when closing a file descriptor. The reason |
68 |
| - // for this is that if an error occurs we don't actually know if the |
69 |
| - // file descriptor was closed or not, and if we retried (for something |
70 |
| - // like EINTR), we might close another valid file descriptor (opened |
71 |
| - // after we closed ours. |
72 |
| - if self.fd > libc::STDERR_FILENO { |
73 |
| - let n = unsafe { libc::close(self.fd) }; |
74 |
| - if n != 0 { |
75 |
| - println!("error {} when closing file descriptor {}", n, self.fd); |
76 |
| - } |
77 |
| - } |
| 46 | + self.inner.write(buf) |
78 | 47 | }
|
79 | 48 | }
|
0 commit comments