|
| 1 | +#[cfg(any(feature = "net", feature = "virtio-vsock"))] |
| 2 | +use alloc::sync::Arc; |
| 3 | +use core::mem::MaybeUninit; |
| 4 | + |
| 5 | +use delegate::delegate; |
| 6 | + |
| 7 | +use crate::fd::eventfd::EventFd; |
| 8 | +#[cfg(feature = "tcp")] |
| 9 | +use crate::fd::socket::tcp; |
| 10 | +#[cfg(feature = "udp")] |
| 11 | +use crate::fd::socket::udp; |
| 12 | +#[cfg(feature = "virtio-vsock")] |
| 13 | +use crate::fd::socket::vsock; |
| 14 | +use crate::fd::stdio::{ |
| 15 | + GenericStderr, GenericStdin, GenericStdout, UhyveStderr, UhyveStdin, UhyveStdout, |
| 16 | +}; |
| 17 | +use crate::fd::{AccessPermission, ObjectInterface, PollEvent, StatusFlags}; |
| 18 | +#[cfg(any(feature = "net", feature = "virtio-vsock"))] |
| 19 | +use crate::fd::{Endpoint, ListenEndpoint, SocketOption}; |
| 20 | +use crate::fs::mem::{MemDirectoryInterface, RamFileInterface, RomFileInterface}; |
| 21 | +use crate::fs::uhyve::UhyveFileHandle; |
| 22 | +#[cfg(feature = "virtio-fs")] |
| 23 | +use crate::fs::virtio_fs::{VirtioFsDirectoryHandle, VirtioFsFileHandle}; |
| 24 | +use crate::fs::{DirectoryReader, FileAttr, SeekWhence}; |
| 25 | +use crate::io; |
| 26 | + |
| 27 | +pub(crate) enum Fd { |
| 28 | + GenericStdin(GenericStdin), |
| 29 | + GenericStdout(GenericStdout), |
| 30 | + GenericStderr(GenericStderr), |
| 31 | + UhyveStdin(UhyveStdin), |
| 32 | + UhyveStdout(UhyveStdout), |
| 33 | + UhyveStderr(UhyveStderr), |
| 34 | + EventFd(EventFd), |
| 35 | + #[cfg(feature = "tcp")] |
| 36 | + TcpSocket(tcp::Socket), |
| 37 | + #[cfg(feature = "udp")] |
| 38 | + UdpSocket(udp::Socket), |
| 39 | + #[cfg(feature = "virtio-vsock")] |
| 40 | + VsockNullSocket(vsock::NullSocket), |
| 41 | + #[cfg(feature = "virtio-vsock")] |
| 42 | + VsockSocket(vsock::Socket), |
| 43 | + #[cfg(feature = "virtio-fs")] |
| 44 | + VirtioFsFileHandle(VirtioFsFileHandle), |
| 45 | + #[cfg(feature = "virtio-fs")] |
| 46 | + VirtioFsDirectoryHandle(VirtioFsDirectoryHandle), |
| 47 | + RomFileInterface(RomFileInterface), |
| 48 | + RamFileInterface(RamFileInterface), |
| 49 | + MemDirectoryInterface(MemDirectoryInterface), |
| 50 | + DirectoryReader(DirectoryReader), |
| 51 | + UhyveFileHandle(UhyveFileHandle), |
| 52 | +} |
| 53 | + |
| 54 | +macro_rules! fd_from { |
| 55 | + () => {}; |
| 56 | + ( |
| 57 | + $(#[$meta:meta])* |
| 58 | + $ident:ident($ty:ty), |
| 59 | + $($rest:tt)* |
| 60 | + ) => { |
| 61 | + $(#[$meta])* |
| 62 | + impl From<$ty> for Fd { |
| 63 | + fn from(value: $ty) -> Self { |
| 64 | + Self::$ident(value) |
| 65 | + } |
| 66 | + } |
| 67 | + |
| 68 | + fd_from!($($rest)*); |
| 69 | + }; |
| 70 | +} |
| 71 | + |
| 72 | +fd_from! { |
| 73 | + GenericStdin(GenericStdin), |
| 74 | + GenericStdout(GenericStdout), |
| 75 | + GenericStderr(GenericStderr), |
| 76 | + UhyveStdin(UhyveStdin), |
| 77 | + UhyveStdout(UhyveStdout), |
| 78 | + UhyveStderr(UhyveStderr), |
| 79 | + EventFd(EventFd), |
| 80 | + #[cfg(feature = "tcp")] |
| 81 | + TcpSocket(tcp::Socket), |
| 82 | + #[cfg(feature = "udp")] |
| 83 | + UdpSocket(udp::Socket), |
| 84 | + #[cfg(feature = "virtio-vsock")] |
| 85 | + VsockNullSocket(vsock::NullSocket), |
| 86 | + #[cfg(feature = "virtio-vsock")] |
| 87 | + VsockSocket(vsock::Socket), |
| 88 | + #[cfg(feature = "virtio-fs")] |
| 89 | + VirtioFsFileHandle(VirtioFsFileHandle), |
| 90 | + #[cfg(feature = "virtio-fs")] |
| 91 | + VirtioFsDirectoryHandle(VirtioFsDirectoryHandle), |
| 92 | + RomFileInterface(RomFileInterface), |
| 93 | + RamFileInterface(RamFileInterface), |
| 94 | + MemDirectoryInterface(MemDirectoryInterface), |
| 95 | + DirectoryReader(DirectoryReader), |
| 96 | + UhyveFileHandle(UhyveFileHandle), |
| 97 | +} |
| 98 | + |
| 99 | +impl ObjectInterface for Fd { |
| 100 | + delegate! { |
| 101 | + to match self { |
| 102 | + Self::GenericStdin(fd) => fd, |
| 103 | + Self::GenericStdout(fd) => fd, |
| 104 | + Self::GenericStderr(fd) => fd, |
| 105 | + Self::UhyveStdin(fd) => fd, |
| 106 | + Self::UhyveStdout(fd) => fd, |
| 107 | + Self::UhyveStderr(fd) => fd, |
| 108 | + Self::EventFd(fd) => fd, |
| 109 | + #[cfg(feature = "tcp")] |
| 110 | + Self::TcpSocket(fd) => fd, |
| 111 | + #[cfg(feature = "udp")] |
| 112 | + Self::UdpSocket(fd) => fd, |
| 113 | + #[cfg(feature = "virtio-vsock")] |
| 114 | + Self::VsockNullSocket(fd) => fd, |
| 115 | + #[cfg(feature = "virtio-vsock")] |
| 116 | + Self::VsockSocket(fd) => fd, |
| 117 | + #[cfg(feature = "virtio-fs")] |
| 118 | + Self::VirtioFsFileHandle(fd) => fd, |
| 119 | + #[cfg(feature = "virtio-fs")] |
| 120 | + Self::VirtioFsDirectoryHandle(fd) => fd, |
| 121 | + Self::RomFileInterface(fd) => fd, |
| 122 | + Self::RamFileInterface(fd) => fd, |
| 123 | + Self::MemDirectoryInterface(fd) => fd, |
| 124 | + Self::DirectoryReader(fd) => fd, |
| 125 | + Self::UhyveFileHandle(fd) => fd, |
| 126 | + } { |
| 127 | + async fn poll(&self, event: PollEvent) -> io::Result<PollEvent>; |
| 128 | + async fn read(&self, buf: &mut [u8]) -> io::Result<usize>; |
| 129 | + async fn write(&self, buf: &[u8]) -> io::Result<usize>; |
| 130 | + async fn lseek(&self, offset: isize, whence: SeekWhence) -> io::Result<isize>; |
| 131 | + async fn fstat(&self) -> io::Result<FileAttr>; |
| 132 | + async fn getdents(&self, buf: &mut [MaybeUninit<u8>]) -> io::Result<usize>; |
| 133 | + #[cfg(any(feature = "net", feature = "virtio-vsock"))] |
| 134 | + async fn accept(&mut self) -> io::Result<(Arc<async_lock::RwLock<Fd>>, Endpoint)>; |
| 135 | + #[cfg(any(feature = "net", feature = "virtio-vsock"))] |
| 136 | + async fn connect(&mut self, endpoint: Endpoint) -> io::Result<()>; |
| 137 | + #[cfg(any(feature = "net", feature = "virtio-vsock"))] |
| 138 | + async fn bind(&mut self, _name: ListenEndpoint) -> io::Result<()>; |
| 139 | + #[cfg(any(feature = "net", feature = "virtio-vsock"))] |
| 140 | + async fn listen(&mut self, _backlog: i32) -> io::Result<()>; |
| 141 | + #[cfg(any(feature = "net", feature = "virtio-vsock"))] |
| 142 | + async fn setsockopt(&self, _opt: SocketOption, _optval: bool) -> io::Result<()>; |
| 143 | + #[cfg(any(feature = "net", feature = "virtio-vsock"))] |
| 144 | + async fn getsockopt(&self, _opt: SocketOption) -> io::Result<bool>; |
| 145 | + #[cfg(any(feature = "net", feature = "virtio-vsock"))] |
| 146 | + async fn getsockname(&self) -> io::Result<Option<Endpoint>>; |
| 147 | + #[cfg(any(feature = "net", feature = "virtio-vsock"))] |
| 148 | + #[allow(dead_code)] |
| 149 | + async fn getpeername(&self) -> io::Result<Option<Endpoint>>; |
| 150 | + #[cfg(any(feature = "net", feature = "virtio-vsock"))] |
| 151 | + async fn recvfrom(&self, _buffer: &mut [MaybeUninit<u8>]) -> io::Result<(usize, Endpoint)>; |
| 152 | + #[cfg(any(feature = "net", feature = "virtio-vsock"))] |
| 153 | + async fn sendto(&self, _buffer: &[u8], _endpoint: Endpoint) -> io::Result<usize>; |
| 154 | + #[cfg(any(feature = "net", feature = "virtio-vsock"))] |
| 155 | + async fn shutdown(&self, _how: i32) -> io::Result<()>; |
| 156 | + async fn status_flags(&self) -> io::Result<StatusFlags>; |
| 157 | + async fn set_status_flags(&mut self, _status_flags: StatusFlags) -> io::Result<()>; |
| 158 | + async fn truncate(&self, _size: usize) -> io::Result<()>; |
| 159 | + async fn chmod(&self, _access_permission: AccessPermission) -> io::Result<()>; |
| 160 | + async fn isatty(&self) -> io::Result<bool>; |
| 161 | + } |
| 162 | + } |
| 163 | +} |
0 commit comments