]> git.proxmox.com Git - rustc.git/blame - src/libstd/sys/vxworks/pipe.rs
New upstream version 1.45.0+dfsg1
[rustc.git] / src / libstd / sys / vxworks / pipe.rs
CommitLineData
416331ca 1use crate::io::{self, IoSlice, IoSliceMut};
416331ca 2use crate::mem;
60c5eb7d 3use crate::sync::atomic::AtomicBool;
416331ca
XL
4use crate::sys::fd::FileDesc;
5use crate::sys::{cvt, cvt_r};
60c5eb7d 6use libc::{self /*, c_int apparently not used? */};
416331ca
XL
7
8pub struct AnonPipe(FileDesc);
9
10pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
11 static INVALID: AtomicBool = AtomicBool::new(false);
12
13 let mut fds = [0; 2];
14 cvt(unsafe { libc::pipe(fds.as_mut_ptr()) })?;
15
16 let fd0 = FileDesc::new(fds[0]);
17 let fd1 = FileDesc::new(fds[1]);
18 fd0.set_cloexec()?;
19 fd1.set_cloexec()?;
20 Ok((AnonPipe(fd0), AnonPipe(fd1)))
21}
22
23impl AnonPipe {
24 pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
25 self.0.read(buf)
26 }
f9f354fc 27
416331ca 28 pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
60c5eb7d
XL
29 self.0.read_vectored(bufs)
30 }
416331ca 31
f9f354fc
XL
32 #[inline]
33 pub fn is_read_vectored(&self) -> bool {
34 self.0.is_read_vectored()
35 }
36
416331ca
XL
37 pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
38 self.0.write(buf)
39 }
40
60c5eb7d
XL
41 pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
42 self.0.write_vectored(bufs)
43 }
416331ca 44
f9f354fc
XL
45 #[inline]
46 pub fn is_write_vectored(&self) -> bool {
47 self.0.is_write_vectored()
48 }
49
60c5eb7d
XL
50 pub fn fd(&self) -> &FileDesc {
51 &self.0
52 }
53 pub fn into_fd(self) -> FileDesc {
54 self.0
55 }
416331ca
XL
56 pub fn diverge(&self) -> ! {
57 panic!()
60c5eb7d 58 }
416331ca
XL
59}
60
60c5eb7d 61pub fn read2(p1: AnonPipe, v1: &mut Vec<u8>, p2: AnonPipe, v2: &mut Vec<u8>) -> io::Result<()> {
416331ca
XL
62 // Set both pipes into nonblocking mode as we're gonna be reading from both
63 // in the `select` loop below, and we wouldn't want one to block the other!
64 let p1 = p1.into_fd();
65 let p2 = p2.into_fd();
66 p1.set_nonblocking_pipe(true)?;
67 p2.set_nonblocking_pipe(true)?;
68
69 let mut fds: [libc::pollfd; 2] = unsafe { mem::zeroed() };
70 fds[0].fd = p1.raw();
71 fds[0].events = libc::POLLIN;
72 fds[1].fd = p2.raw();
73 fds[1].events = libc::POLLIN;
74 loop {
75 // wait for either pipe to become readable using `poll`
76 cvt_r(|| unsafe { libc::poll(fds.as_mut_ptr(), 2, -1) })?;
77
78 if fds[0].revents != 0 && read(&p1, v1)? {
79 p2.set_nonblocking_pipe(false)?;
dfeec247 80 return p2.read_to_end(v2).map(drop);
416331ca
XL
81 }
82 if fds[1].revents != 0 && read(&p2, v2)? {
83 p1.set_nonblocking_pipe(false)?;
dfeec247 84 return p1.read_to_end(v1).map(drop);
416331ca
XL
85 }
86 }
87
88 // Read as much as we can from each pipe, ignoring EWOULDBLOCK or
89 // EAGAIN. If we hit EOF, then this will happen because the underlying
90 // reader will return Ok(0), in which case we'll see `Ok` ourselves. In
91 // this case we flip the other fd back into blocking mode and read
92 // whatever's leftover on that file descriptor.
93 fn read(fd: &FileDesc, dst: &mut Vec<u8>) -> Result<bool, io::Error> {
94 match fd.read_to_end(dst) {
95 Ok(_) => Ok(true),
96 Err(e) => {
60c5eb7d
XL
97 if e.raw_os_error() == Some(libc::EWOULDBLOCK)
98 || e.raw_os_error() == Some(libc::EAGAIN)
99 {
416331ca
XL
100 Ok(false)
101 } else {
102 Err(e)
103 }
104 }
105 }
106 }
107}