Skip to main content

compio_driver/sys/pal/unix/
mod.rs

1use std::io;
2pub use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
3
4pub use libc::cmsghdr as CmsgHeader;
5use rustix::{
6    fs::{AtFlags, CWD, Stat},
7    io::Errno,
8};
9use smallvec::SmallVec;
10
11use crate::sys::prelude::*;
12
13mod_use![stat, pipe, socket];
14
15/// Per-socket state needed by the asynchronous operations.
16pub trait AsSocketState: AsFd {
17    /// Whether the socket is known to be empty, so that a receive should arm
18    /// poll before its first attempt.
19    fn recv_poll_first(&self) -> bool {
20        false
21    }
22
23    /// Same as [`AsSocketState::recv_poll_first`], for accept.
24    fn accept_poll_first(&self) -> bool {
25        false
26    }
27
28    /// Update the state from a receive completion.
29    fn set_recv(&self, extra: &Extra) {
30        let _ = extra;
31    }
32
33    /// Same as [`AsSocketState::set_recv`], for accept.
34    fn set_accept(&self, extra: &Extra) {
35        let _ = extra;
36    }
37}
38
39impl<T: AsSocketState> AsSocketState for crate::SharedFd<T> {
40    fn recv_poll_first(&self) -> bool {
41        (**self).recv_poll_first()
42    }
43
44    fn accept_poll_first(&self) -> bool {
45        (**self).accept_poll_first()
46    }
47
48    fn set_recv(&self, extra: &Extra) {
49        (**self).set_recv(extra)
50    }
51
52    fn set_accept(&self, extra: &Extra) {
53        (**self).set_accept(extra)
54    }
55}
56
57pub mod reexport {}
58
59/// One item in local or more items on heap.
60pub type Multi<T> = SmallVec<[T; 1]>;
61
62/// The interest to poll a file descriptor.
63#[derive(Debug, Clone, Copy, PartialEq, Eq)]
64pub enum Interest {
65    /// Represents a read operation.
66    Readable,
67    /// Represents a write operation.
68    Writable,
69}
70
71/// A special file descriptor that always refers to the current working
72/// directory. It represents [`AT_FDCWD`](libc::AT_FDCWD) in libc.
73pub struct CurrentDir;
74
75impl AsRawFd for CurrentDir {
76    fn as_raw_fd(&self) -> RawFd {
77        CWD.as_raw_fd()
78    }
79}
80
81impl AsFd for CurrentDir {
82    fn as_fd(&self) -> BorrowedFd<'_> {
83        unsafe { BorrowedFd::borrow_raw(libc::AT_FDCWD) }
84    }
85}
86
87/// Execute the function, retry on interruption, return [`Poll::Pending`] if
88/// it's not finished yet, or return the result otherwise.
89pub fn poll_io<R, E, F>(mut f: F) -> Poll<io::Result<R>>
90where
91    F: FnMut() -> std::result::Result<R, E>,
92    E: Into<io::Error>,
93{
94    loop {
95        match f().map_err(Into::into) {
96            Ok(res) => break Poll::Ready(Ok(res)),
97            Err(e) => match Errno::from_io_error(&e) {
98                Some(Errno::WOULDBLOCK | Errno::INPROGRESS) => return Poll::Pending,
99                Some(Errno::INTR) => continue,
100                _ => return Poll::Ready(Err(e)),
101            },
102        }
103    }
104}