1use alloc::boxed::Box;
2use alloc::sync::Arc;
3use alloc::vec::Vec;
4use core::future::{self, Future};
5use core::task::Poll::{Pending, Ready};
6use core::time::Duration;
7
8use async_trait::async_trait;
9#[cfg(any(feature = "tcp", feature = "udp"))]
10use smoltcp::wire::{IpEndpoint, IpListenEndpoint};
11
12use crate::arch::kernel::core_local::core_scheduler;
13use crate::executor::block_on;
14use crate::fs::{DirectoryEntry, FileAttr, SeekWhence};
15use crate::io;
16
17mod eventfd;
18#[cfg(any(feature = "tcp", feature = "udp", feature = "vsock"))]
19pub(crate) mod socket;
20pub(crate) mod stdio;
21
22pub(crate) const STDIN_FILENO: FileDescriptor = 0;
23pub(crate) const STDOUT_FILENO: FileDescriptor = 1;
24pub(crate) const STDERR_FILENO: FileDescriptor = 2;
25
26#[cfg(any(feature = "tcp", feature = "udp", feature = "vsock"))]
27#[derive(Debug)]
28pub(crate) enum Endpoint {
29 #[cfg(any(feature = "tcp", feature = "udp"))]
30 Ip(IpEndpoint),
31 #[cfg(feature = "vsock")]
32 Vsock(socket::vsock::VsockEndpoint),
33}
34
35#[cfg(any(feature = "tcp", feature = "udp", feature = "vsock"))]
36#[derive(Debug)]
37pub(crate) enum ListenEndpoint {
38 #[cfg(any(feature = "tcp", feature = "udp"))]
39 Ip(IpListenEndpoint),
40 #[cfg(feature = "vsock")]
41 Vsock(socket::vsock::VsockListenEndpoint),
42}
43
44#[allow(dead_code)]
45#[derive(Debug, PartialEq)]
46pub(crate) enum SocketOption {
47 TcpNoDelay,
48}
49
50#[allow(dead_code)]
51#[derive(Debug, PartialEq)]
52pub(crate) enum IoCtl {
53 NonBlocking,
54}
55
56pub(crate) type FileDescriptor = i32;
57
58bitflags! {
59 #[derive(Debug, Copy, Clone, Default)]
61 pub struct OpenOption: i32 {
62 const O_RDONLY = 0o0000;
63 const O_WRONLY = 0o0001;
64 const O_RDWR = 0o0002;
65 const O_CREAT = 0o0100;
66 const O_EXCL = 0o0200;
67 const O_TRUNC = 0o1000;
68 const O_APPEND = 0o2000;
69 const O_DIRECT = 0o40000;
70 const O_DIRECTORY = 0o200_000;
71 }
72}
73
74bitflags! {
75 #[derive(Debug, Copy, Clone, Default)]
76 pub struct PollEvent: i16 {
77 const POLLIN = 0x1;
78 const POLLPRI = 0x2;
79 const POLLOUT = 0x4;
80 const POLLERR = 0x8;
81 const POLLHUP = 0x10;
82 const POLLNVAL = 0x20;
83 const POLLRDNORM = 0x040;
84 const POLLRDBAND = 0x080;
85 const POLLWRNORM = 0x0100;
86 const POLLWRBAND = 0x0200;
87 const POLLRDHUP = 0x2000;
88 }
89}
90
91#[repr(C)]
92#[derive(Debug, Default, Copy, Clone)]
93pub struct PollFd {
94 pub fd: i32,
96 pub events: PollEvent,
98 pub revents: PollEvent,
100}
101
102bitflags! {
103 #[derive(Debug, Default, Copy, Clone)]
104 pub struct EventFlags: i16 {
105 const EFD_SEMAPHORE = 0o1;
106 const EFD_NONBLOCK = 0o4000;
107 const EFD_CLOEXEC = 0o40000;
108 }
109}
110
111bitflags! {
112 #[derive(Debug, Copy, Clone)]
113 pub struct AccessPermission: u32 {
114 const S_IFMT = 0o170_000;
115 const S_IFSOCK = 0o140_000;
116 const S_IFLNK = 0o120_000;
117 const S_IFREG = 0o100_000;
118 const S_IFBLK = 0o060_000;
119 const S_IFDIR = 0o040_000;
120 const S_IFCHR = 0o020_000;
121 const S_IFIFO = 0o010_000;
122 const S_IRUSR = 0o400;
123 const S_IWUSR = 0o200;
124 const S_IXUSR = 0o100;
125 const S_IRWXU = 0o700;
126 const S_IRGRP = 0o040;
127 const S_IWGRP = 0o020;
128 const S_IXGRP = 0o010;
129 const S_IRWXG = 0o070;
130 const S_IROTH = 0o004;
131 const S_IWOTH = 0o002;
132 const S_IXOTH = 0o001;
133 const S_IRWXO = 0o007;
134 const _ = !0;
136 }
137}
138
139impl Default for AccessPermission {
140 fn default() -> Self {
141 AccessPermission::from_bits(0o666).unwrap()
142 }
143}
144
145#[async_trait]
146pub(crate) trait ObjectInterface: Sync + Send + core::fmt::Debug {
147 async fn poll(&self, _event: PollEvent) -> io::Result<PollEvent> {
149 Ok(PollEvent::empty())
150 }
151
152 async fn read(&self, _buf: &mut [u8]) -> io::Result<usize> {
155 Err(io::Error::ENOSYS)
156 }
157
158 async fn write(&self, _buf: &[u8]) -> io::Result<usize> {
161 Err(io::Error::ENOSYS)
162 }
163
164 async fn lseek(&self, _offset: isize, _whence: SeekWhence) -> io::Result<isize> {
166 Err(io::Error::EINVAL)
167 }
168
169 async fn fstat(&self) -> io::Result<FileAttr> {
171 Err(io::Error::EINVAL)
172 }
173
174 async fn readdir(&self) -> io::Result<Vec<DirectoryEntry>> {
178 Err(io::Error::EINVAL)
179 }
180
181 #[cfg(any(feature = "tcp", feature = "udp", feature = "vsock"))]
183 async fn accept(&self) -> io::Result<(Arc<dyn ObjectInterface>, Endpoint)> {
184 Err(io::Error::EINVAL)
185 }
186
187 #[cfg(any(feature = "tcp", feature = "udp", feature = "vsock"))]
189 async fn connect(&self, _endpoint: Endpoint) -> io::Result<()> {
190 Err(io::Error::EINVAL)
191 }
192
193 #[cfg(any(feature = "tcp", feature = "udp", feature = "vsock"))]
195 async fn bind(&self, _name: ListenEndpoint) -> io::Result<()> {
196 Err(io::Error::EINVAL)
197 }
198
199 #[cfg(any(feature = "tcp", feature = "udp", feature = "vsock"))]
201 async fn listen(&self, _backlog: i32) -> io::Result<()> {
202 Err(io::Error::EINVAL)
203 }
204
205 #[cfg(any(feature = "tcp", feature = "udp", feature = "vsock"))]
207 async fn setsockopt(&self, _opt: SocketOption, _optval: bool) -> io::Result<()> {
208 Err(io::Error::ENOTSOCK)
209 }
210
211 #[cfg(any(feature = "tcp", feature = "udp", feature = "vsock"))]
213 async fn getsockopt(&self, _opt: SocketOption) -> io::Result<bool> {
214 Err(io::Error::ENOTSOCK)
215 }
216
217 #[cfg(any(feature = "tcp", feature = "udp", feature = "vsock"))]
219 async fn getsockname(&self) -> io::Result<Option<Endpoint>> {
220 Ok(None)
221 }
222
223 #[cfg(any(feature = "tcp", feature = "udp", feature = "vsock"))]
225 #[allow(dead_code)]
226 async fn getpeername(&self) -> io::Result<Option<Endpoint>> {
227 Ok(None)
228 }
229
230 #[cfg(any(feature = "tcp", feature = "udp", feature = "vsock"))]
232 async fn recvfrom(&self, _buffer: &mut [u8]) -> io::Result<(usize, Endpoint)> {
233 Err(io::Error::ENOSYS)
234 }
235
236 #[cfg(any(feature = "tcp", feature = "udp", feature = "vsock"))]
244 async fn sendto(&self, _buffer: &[u8], _endpoint: Endpoint) -> io::Result<usize> {
245 Err(io::Error::ENOSYS)
246 }
247
248 #[cfg(any(feature = "tcp", feature = "udp", feature = "vsock"))]
250 async fn shutdown(&self, _how: i32) -> io::Result<()> {
251 Err(io::Error::ENOSYS)
252 }
253
254 async fn ioctl(&self, _cmd: IoCtl, _value: bool) -> io::Result<()> {
257 Err(io::Error::ENOSYS)
258 }
259}
260
261pub(crate) fn read(fd: FileDescriptor, buf: &mut [u8]) -> io::Result<usize> {
262 let obj = get_object(fd)?;
263
264 if buf.is_empty() {
265 return Ok(0);
266 }
267
268 block_on(obj.read(buf), None)
269}
270
271pub(crate) fn lseek(fd: FileDescriptor, offset: isize, whence: SeekWhence) -> io::Result<isize> {
272 let obj = get_object(fd)?;
273
274 block_on(obj.lseek(offset, whence), None)
275}
276
277pub(crate) fn write(fd: FileDescriptor, buf: &[u8]) -> io::Result<usize> {
278 let obj = get_object(fd)?;
279
280 if buf.is_empty() {
281 return Ok(0);
282 }
283
284 block_on(obj.write(buf), None)
285}
286
287async fn poll_fds(fds: &mut [PollFd]) -> io::Result<u64> {
288 future::poll_fn(|cx| {
289 let mut counter: u64 = 0;
290
291 for i in &mut *fds {
292 let fd = i.fd;
293 i.revents = PollEvent::empty();
294 let mut pinned_obj = core::pin::pin!(core_scheduler().get_object(fd));
295 if let Ready(Ok(obj)) = pinned_obj.as_mut().poll(cx) {
296 let mut pinned = core::pin::pin!(obj.poll(i.events));
297 if let Ready(Ok(e)) = pinned.as_mut().poll(cx) {
298 if !e.is_empty() {
299 counter += 1;
300 i.revents = e;
301 }
302 }
303 }
304 }
305
306 if counter > 0 {
307 Ready(Ok(counter))
308 } else {
309 Pending
310 }
311 })
312 .await
313}
314
315pub fn poll(fds: &mut [PollFd], timeout: Option<Duration>) -> io::Result<u64> {
322 let result = block_on(poll_fds(fds), timeout);
323 if let Err(ref e) = result {
324 if timeout.is_some() {
325 if *e == io::Error::EAGAIN {
327 return Ok(0);
328 }
329 }
330 }
331
332 result
333}
334
335pub fn fstat(fd: FileDescriptor) -> io::Result<FileAttr> {
336 let obj = get_object(fd)?;
337 block_on(obj.fstat(), None)
338}
339
340pub fn eventfd(initval: u64, flags: EventFlags) -> io::Result<FileDescriptor> {
359 let obj = self::eventfd::EventFd::new(initval, flags);
360
361 let fd = block_on(core_scheduler().insert_object(Arc::new(obj)), None)?;
362
363 Ok(fd)
364}
365
366pub(crate) fn get_object(fd: FileDescriptor) -> io::Result<Arc<dyn ObjectInterface>> {
367 block_on(core_scheduler().get_object(fd), None)
368}
369
370pub(crate) fn insert_object(obj: Arc<dyn ObjectInterface>) -> io::Result<FileDescriptor> {
371 block_on(core_scheduler().insert_object(obj), None)
372}
373
374pub(crate) fn dup_object(fd: FileDescriptor) -> io::Result<FileDescriptor> {
379 block_on(core_scheduler().dup_object(fd), None)
380}
381
382pub(crate) fn remove_object(fd: FileDescriptor) -> io::Result<Arc<dyn ObjectInterface>> {
383 block_on(core_scheduler().remove_object(fd), None)
384}