starnix_uapi/
vfs.rs

1// Copyright 2024 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use bitflags::bitflags;
6use linux_uapi as uapi;
7use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
8
9pub const EPOLLWAKEUP: u32 = 1 << 29;
10pub const EPOLLONESHOT: u32 = 1 << 30;
11pub const EPOLLET: u32 = 1 << 31;
12
13bitflags::bitflags! {
14    #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
15    pub struct FdEvents: u32 {
16        const POLLIN = uapi::POLLIN;
17        const POLLPRI = uapi::POLLPRI;
18        const POLLOUT = uapi::POLLOUT;
19        const POLLERR = uapi::POLLERR;
20        const POLLHUP = uapi::POLLHUP;
21        const POLLNVAL = uapi::POLLNVAL;
22        const POLLRDNORM = uapi::POLLRDNORM;
23        const POLLRDBAND = uapi::POLLRDBAND;
24        const POLLWRNORM = uapi::POLLWRNORM;
25        const POLLWRBAND = uapi::POLLWRBAND;
26        const POLLMSG = uapi::POLLMSG;
27        const POLLREMOVE = uapi::POLLREMOVE;
28        const POLLRDHUP = uapi::POLLRDHUP;
29        const EPOLLET = EPOLLET;
30        const EPOLLONESHOT = EPOLLONESHOT;
31        const EPOLLWAKEUP = EPOLLWAKEUP;
32    }
33}
34
35impl FdEvents {
36    /// Build events from the given value, truncating any bits that do not correspond to an event.
37    pub fn from_u64(value: u64) -> Self {
38        Self::from_bits_truncate((value & (u32::MAX as u64)) as u32)
39    }
40
41    /// This function adds `POLLRDNORM` and `POLLWRNORM` to the FdEvents return
42    /// from the FileOps because these FdEvents are equivalent to `POLLIN` and
43    /// `POLLOUT`, respectively, in the Linux UAPI. For example, polling with
44    /// events = POLLIN | POLLRDNORM will always return the same value for both
45    /// bits in revents.
46    ///
47    /// See https://man7.org/linux/man-pages/man2/poll.2.html
48    pub fn add_equivalent_fd_events(self) -> Self {
49        let mut events = self;
50        if events.contains(FdEvents::POLLIN) {
51            events |= FdEvents::POLLRDNORM;
52        }
53        if events.contains(FdEvents::POLLOUT) {
54            events |= FdEvents::POLLWRNORM;
55        }
56        events
57    }
58}
59
60#[repr(C)]
61#[derive(IntoBytes, KnownLayout, FromBytes, Immutable)]
62pub struct EpollEvent(uapi::epoll_event);
63
64impl EpollEvent {
65    pub fn new(events: FdEvents, data: u64) -> Self {
66        Self(uapi::epoll_event { events: events.bits(), data, ..Default::default() })
67    }
68
69    pub fn events(&self) -> FdEvents {
70        FdEvents::from_bits_retain(self.0.events)
71    }
72
73    pub fn ignore(&mut self, events_to_ignore: FdEvents) {
74        let mut previous_events = self.events();
75        previous_events.remove(events_to_ignore);
76        self.0.events = previous_events.bits();
77    }
78
79    pub fn data(&self) -> u64 {
80        self.0.data
81    }
82}
83
84bitflags! {
85    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
86    pub struct ResolveFlags: u32 {
87        const NO_XDEV = uapi::RESOLVE_NO_XDEV;
88        const NO_MAGICLINKS = uapi::RESOLVE_NO_MAGICLINKS;
89        const NO_SYMLINKS = uapi::RESOLVE_NO_SYMLINKS;
90        const BENEATH = uapi::RESOLVE_BENEATH;
91        const IN_ROOT = uapi::RESOLVE_IN_ROOT;
92        const CACHED = uapi::RESOLVE_CACHED;
93    }
94}