1use crate::PipeReader;
2use crate::PipeWriter;
3use libc::c_int;
4use std::fs::File;
5use std::io;
6use std::os::unix::prelude::*;
7
8#[cfg(not(any(target_os = "aix", target_vendor = "apple", target_os = "haiku")))]
14fn pipe2_cloexec() -> io::Result<(OwnedFd, OwnedFd)> {
15 let mut fds: [c_int; 2] = [0; 2];
16 let res = unsafe { libc::pipe2(fds.as_mut_ptr(), libc::O_CLOEXEC) };
17 if res != 0 {
18 return Err(io::Error::last_os_error());
19 }
20 unsafe { Ok((OwnedFd::from_raw_fd(fds[0]), OwnedFd::from_raw_fd(fds[1]))) }
21}
22
23#[cfg(any(target_os = "aix", target_vendor = "apple", target_os = "haiku"))]
24fn pipe2_cloexec() -> io::Result<(OwnedFd, OwnedFd)> {
25 let mut fds: [c_int; 2] = [0; 2];
26 let res = unsafe { libc::pipe(fds.as_mut_ptr()) };
27 if res != 0 {
28 return Err(io::Error::last_os_error());
29 }
30 let owned_fds = unsafe { (OwnedFd::from_raw_fd(fds[0]), OwnedFd::from_raw_fd(fds[1])) };
33 let res = unsafe { libc::fcntl(fds[0], libc::F_SETFD, libc::FD_CLOEXEC) };
34 if res != 0 {
35 return Err(io::Error::last_os_error());
36 }
37 let res = unsafe { libc::fcntl(fds[1], libc::F_SETFD, libc::FD_CLOEXEC) };
38 if res != 0 {
39 return Err(io::Error::last_os_error());
40 }
41 Ok(owned_fds)
42}
43
44pub(crate) fn pipe() -> io::Result<(PipeReader, PipeWriter)> {
45 let (read_fd, write_fd) = pipe2_cloexec()?;
46 Ok((read_fd.into(), write_fd.into()))
47}
48
49pub(crate) fn dup(handle: impl AsFd) -> io::Result<OwnedFd> {
50 handle.as_fd().try_clone_to_owned()
51}
52
53impl IntoRawFd for PipeReader {
54 fn into_raw_fd(self) -> RawFd {
55 self.0.into_raw_fd()
56 }
57}
58
59impl AsRawFd for PipeReader {
60 fn as_raw_fd(&self) -> RawFd {
61 self.0.as_raw_fd()
62 }
63}
64
65impl FromRawFd for PipeReader {
66 unsafe fn from_raw_fd(fd: RawFd) -> PipeReader {
67 unsafe { PipeReader(File::from_raw_fd(fd)) }
68 }
69}
70
71impl From<PipeReader> for OwnedFd {
72 fn from(pr: PipeReader) -> Self {
73 pr.0.into()
74 }
75}
76
77impl AsFd for PipeReader {
78 fn as_fd(&self) -> BorrowedFd<'_> {
79 self.0.as_fd()
80 }
81}
82
83impl From<OwnedFd> for PipeReader {
84 fn from(fd: OwnedFd) -> Self {
85 PipeReader(fd.into())
86 }
87}
88
89impl IntoRawFd for PipeWriter {
90 fn into_raw_fd(self) -> RawFd {
91 self.0.into_raw_fd()
92 }
93}
94
95impl AsRawFd for PipeWriter {
96 fn as_raw_fd(&self) -> RawFd {
97 self.0.as_raw_fd()
98 }
99}
100
101impl FromRawFd for PipeWriter {
102 unsafe fn from_raw_fd(fd: RawFd) -> PipeWriter {
103 unsafe { PipeWriter(File::from_raw_fd(fd)) }
104 }
105}
106
107impl From<PipeWriter> for OwnedFd {
108 fn from(pw: PipeWriter) -> Self {
109 pw.0.into()
110 }
111}
112
113impl AsFd for PipeWriter {
114 fn as_fd(&self) -> BorrowedFd<'_> {
115 self.0.as_fd()
116 }
117}
118
119impl From<OwnedFd> for PipeWriter {
120 fn from(fd: OwnedFd) -> Self {
121 PipeWriter(fd.into())
122 }
123}