1use std::{
2 borrow::Cow,
3 collections::{HashMap, HashSet},
4 path::PathBuf,
5 sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard, atomic::AtomicU64},
6};
7
8use serde_derive::{Deserialize, Serialize};
9use std::sync::Mutex as StdMutex;
10use tokio::sync::{Mutex as AsyncMutex, watch};
11use virtual_fs::{Pipe, PipeRx, PipeTx, VirtualFile};
12use wasmer_wasix_types::wasi::{EpollType, Fd as WasiFd, Fdflags, Fdflagsext, Filestat, Rights};
13
14use crate::net::socket::InodeSocket;
15
16use super::{
17 InodeGuard, InodeValFilePollGuard, InodeValFilePollGuardMode, InodeWeakGuard, NotificationInner,
18};
19
20#[derive(Debug, Clone)]
21#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
22pub struct Fd {
23 #[cfg_attr(feature = "enable-serde", serde(flatten))]
24 pub inner: FdInner,
25
26 pub open_flags: u16,
30 pub inode: InodeGuard,
31 pub is_stdio: bool,
32}
33
34#[derive(Debug, Clone)]
37#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
38pub struct FdInner {
39 pub rights: Rights,
40 pub rights_inheriting: Rights,
41 pub flags: Fdflags, pub offset: Arc<AtomicU64>, pub fd_flags: Fdflagsext, }
45
46impl Fd {
47 pub const READ: u16 = 1;
49 pub const WRITE: u16 = 2;
51 pub const APPEND: u16 = 4;
54 pub const TRUNCATE: u16 = 8;
59 pub const CREATE: u16 = 16;
64}
65
66#[derive(Debug)]
68#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
69pub struct InodeVal {
70 pub stat: RwLock<Filestat>,
71 pub is_preopened: bool,
72 pub name: RwLock<Cow<'static, str>>,
73 pub kind: RwLock<Kind>,
74}
75
76impl InodeVal {
77 pub fn read(&self) -> RwLockReadGuard<'_, Kind> {
78 self.kind.read().unwrap()
79 }
80
81 pub fn write(&self) -> RwLockWriteGuard<'_, Kind> {
82 self.kind.write().unwrap()
83 }
84}
85
86#[derive(Debug, Clone, Serialize, Deserialize)]
87pub struct EpollFd {
88 pub events: EpollType,
90 pub ptr: u64,
92 pub fd: WasiFd,
94 pub data1: u32,
96 pub data2: u64,
98}
99
100#[derive(Debug, Default, Serialize, Deserialize)]
102pub struct EpollInterest {
103 pub interest: HashSet<(WasiFd, EpollType)>,
106}
107
108#[derive(Debug)]
110pub struct EpollJoinGuard {
111 pub(crate) fd_guard: InodeValFilePollGuard,
112}
113impl Drop for EpollJoinGuard {
114 fn drop(&mut self) {
115 match &self.fd_guard.mode {
116 InodeValFilePollGuardMode::File(_) => {
117 }
119 InodeValFilePollGuardMode::Socket { inner } => {
120 let mut inner = inner.protected.write().unwrap();
121 inner.remove_handler();
122 }
123 InodeValFilePollGuardMode::EventNotifications(inner) => {
124 inner.remove_interest_handler();
125 }
126 InodeValFilePollGuardMode::DuplexPipe { pipe } => {
127 let inner = pipe.write().unwrap();
128 inner.remove_interest_handler();
129 }
130 InodeValFilePollGuardMode::PipeRx { rx } => {
131 let inner = rx.write().unwrap();
132 inner.remove_interest_handler();
133 }
134 InodeValFilePollGuardMode::PipeTx { .. } => {
135 }
137 }
138 }
139}
140
141pub type EpollSubscriptions = HashMap<WasiFd, (EpollFd, Vec<EpollJoinGuard>)>;
142
143#[derive(Debug)]
146#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
147pub enum Kind {
148 File {
149 #[cfg_attr(feature = "enable-serde", serde(skip))]
151 handle: Option<Arc<RwLock<Box<dyn VirtualFile + Send + Sync + 'static>>>>,
152 path: PathBuf,
155 fd: Option<u32>,
160 },
161 #[cfg_attr(feature = "enable-serde", serde(skip))]
162 Socket {
163 socket: InodeSocket,
165 },
166 #[cfg_attr(feature = "enable-serde", serde(skip))]
167 PipeTx {
168 tx: PipeTx,
169 },
170 #[cfg_attr(feature = "enable-serde", serde(skip))]
171 PipeRx {
172 rx: PipeRx,
173 },
174 #[cfg_attr(feature = "enable-serde", serde(skip))]
175 DuplexPipe {
176 pipe: Pipe,
177 },
178 Epoll {
179 subscriptions: Arc<StdMutex<EpollSubscriptions>>,
181 tx: Arc<watch::Sender<EpollInterest>>,
183 rx: Arc<AsyncMutex<watch::Receiver<EpollInterest>>>,
186 },
187 Dir {
188 parent: InodeWeakGuard,
190 path: PathBuf,
193 entries: HashMap<String, InodeGuard>,
195 },
196 Root {
201 entries: HashMap<String, InodeGuard>,
202 },
203 Symlink {
210 base_po_dir: WasiFd,
212 path_to_symlink: PathBuf,
214 relative_path: PathBuf,
216 },
217 Buffer {
218 buffer: Vec<u8>,
219 },
220 EventNotifications {
221 inner: Arc<NotificationInner>,
222 },
223}