about summary refs log tree commit diff
path: root/src/libstd/sys/redox/pipe.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd/sys/redox/pipe.rs')
-rw-r--r--src/libstd/sys/redox/pipe.rs105
1 files changed, 105 insertions, 0 deletions
diff --git a/src/libstd/sys/redox/pipe.rs b/src/libstd/sys/redox/pipe.rs
new file mode 100644
index 00000000000..f77f1e0dc68
--- /dev/null
+++ b/src/libstd/sys/redox/pipe.rs
@@ -0,0 +1,105 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use io;
+use libc::{self, c_int};
+use sys::fd::FileDesc;
+
+////////////////////////////////////////////////////////////////////////////////
+// Anonymous pipes
+////////////////////////////////////////////////////////////////////////////////
+
+pub struct AnonPipe(FileDesc);
+
+pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
+    let mut fds = [0; 2];
+
+    libc::pipe2(&mut fds, libc::O_CLOEXEC).map_err(|err| io::Error::from_raw_os_error(err.errno))?;
+
+    let fd0 = FileDesc::new(fds[0] as c_int);
+    let fd1 = FileDesc::new(fds[1] as c_int);
+    Ok((AnonPipe::from_fd(fd0)?, AnonPipe::from_fd(fd1)?))
+}
+
+impl AnonPipe {
+    pub fn from_fd(fd: FileDesc) -> io::Result<AnonPipe> {
+        fd.set_cloexec()?;
+        Ok(AnonPipe(fd))
+    }
+
+    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
+        self.0.read(buf)
+    }
+
+    pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
+        self.0.read_to_end(buf)
+    }
+
+    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
+        self.0.write(buf)
+    }
+
+    pub fn fd(&self) -> &FileDesc { &self.0 }
+    pub fn into_fd(self) -> FileDesc { self.0 }
+}
+
+pub fn read2(_p1: AnonPipe,
+             _v1: &mut Vec<u8>,
+             _p2: AnonPipe,
+             _v2: &mut Vec<u8>) -> io::Result<()> {
+    unimplemented!();
+    /*
+    // Set both pipes into nonblocking mode as we're gonna be reading from both
+    // in the `select` loop below, and we wouldn't want one to block the other!
+    let p1 = p1.into_fd();
+    let p2 = p2.into_fd();
+    p1.set_nonblocking(true)?;
+    p2.set_nonblocking(true)?;
+
+    let max = cmp::max(p1.raw(), p2.raw());
+    loop {
+        // wait for either pipe to become readable using `select`
+        cvt_r(|| unsafe {
+            let mut read: libc::fd_set = mem::zeroed();
+            libc::FD_SET(p1.raw(), &mut read);
+            libc::FD_SET(p2.raw(), &mut read);
+            libc::select(max + 1, &mut read, ptr::null_mut(), ptr::null_mut(),
+                         ptr::null_mut())
+        })?;
+
+        // Read as much as we can from each pipe, ignoring EWOULDBLOCK or
+        // EAGAIN. If we hit EOF, then this will happen because the underlying
+        // reader will return Ok(0), in which case we'll see `Ok` ourselves. In
+        // this case we flip the other fd back into blocking mode and read
+        // whatever's leftover on that file descriptor.
+        let read = |fd: &FileDesc, dst: &mut Vec<u8>| {
+            match fd.read_to_end(dst) {
+                Ok(_) => Ok(true),
+                Err(e) => {
+                    if e.raw_os_error() == Some(libc::EWOULDBLOCK) ||
+                       e.raw_os_error() == Some(libc::EAGAIN) {
+                        Ok(false)
+                    } else {
+                        Err(e)
+                    }
+                }
+            }
+        };
+        if read(&p1, v1)? {
+            p2.set_nonblocking(false)?;
+            return p2.read_to_end(v2).map(|_| ());
+        }
+        if read(&p2, v2)? {
+            p1.set_nonblocking(false)?;
+            return p1.read_to_end(v1).map(|_| ());
+        }
+    }
+    */
+}