interprocess/os/unix/
unnamed_pipe.rs1use {
4 super::{c_wrappers, FdOps},
5 crate::{
6 os::unix::unixprelude::*,
7 unnamed_pipe::{Recver as PubRecver, Sender as PubSender},
8 Sealed,
9 },
10 std::{
11 fmt::{self, Debug, Formatter},
12 io,
13 os::fd::OwnedFd,
14 },
15};
16
17#[cfg(feature = "tokio")]
18pub(crate) mod tokio;
19
20#[allow(private_bounds)]
22pub trait UnnamedPipeExt: AsFd + Sealed {
23 #[inline]
33 fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
34 c_wrappers::set_nonblocking(self.as_fd(), nonblocking)
35 }
36}
37#[cfg_attr(feature = "doc_cfg", doc(cfg(unix)))]
38impl UnnamedPipeExt for PubRecver {}
39#[cfg_attr(feature = "doc_cfg", doc(cfg(unix)))]
40impl UnnamedPipeExt for PubSender {}
41
42pub fn pipe(nonblocking: bool) -> io::Result<(PubSender, PubRecver)> {
50 let (success, fds) = unsafe {
51 let mut fds: [c_int; 2] = [0; 2];
52 let result;
53 #[cfg(any(target_os = "linux", target_os = "android"))]
54 {
55 result =
56 libc::pipe2(fds.as_mut_ptr(), if nonblocking { libc::O_NONBLOCK } else { 0 });
57 }
58 #[cfg(not(any(target_os = "linux", target_os = "android")))]
59 {
60 result = libc::pipe(fds.as_mut_ptr());
61 }
62 (result == 0, fds)
63 };
64 if success {
65 let (w, r) = unsafe {
66 let w = OwnedFd::from_raw_fd(fds[1]);
69 let r = OwnedFd::from_raw_fd(fds[0]);
70 (w, r)
71 };
72 let w = PubSender(Sender(FdOps(w)));
73 let r = PubRecver(Recver(FdOps(r)));
74 #[cfg(not(any(target_os = "linux", target_os = "android")))]
75 {
76 if nonblocking {
77 w.set_nonblocking(true)?;
78 r.set_nonblocking(true)?;
79 }
80 }
81 Ok((w, r))
82 } else {
83 Err(io::Error::last_os_error())
84 }
85}
86
87#[inline]
89pub(crate) fn pipe_impl() -> io::Result<(PubSender, PubRecver)> { pipe(false) }
90
91pub(crate) struct Recver(FdOps);
92impl Sealed for Recver {}
93impl Debug for Recver {
94 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
95 f.debug_struct("Recver").field("fd", &self.0 .0.as_raw_fd()).finish()
96 }
97}
98multimacro! {
99 Recver,
100 forward_rbv(FdOps, &),
101 forward_sync_ref_read,
102 forward_try_clone,
103 forward_handle,
104 derive_sync_mut_read,
105}
106
107pub(crate) struct Sender(FdOps);
108impl Sealed for Sender {}
109impl Debug for Sender {
110 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
111 f.debug_struct("Sender").field("fd", &self.0 .0.as_raw_fd()).finish()
112 }
113}
114
115multimacro! {
116 Sender,
117 forward_rbv(FdOps, &),
118 forward_sync_ref_write,
119 forward_try_clone,
120 forward_handle,
121 derive_sync_mut_write,
122}