syscall/scheme/
scheme.rs

1use core::{mem, slice};
2
3use crate::{data::*, error::*, flag::*, number::*, scheme::*, CallerCtx, OpenResult};
4
5pub trait Scheme {
6    fn handle(&self, packet: &mut Packet) {
7        let res = match packet.a {
8            SYS_OPEN => {
9                if let Some(path) = unsafe { str_from_raw_parts(packet.b as *const u8, packet.c) } {
10                    convert_in_scheme_handle(
11                        packet,
12                        self.xopen(path, packet.d, &CallerCtx::from_packet(&packet)),
13                    )
14                } else {
15                    Err(Error::new(EINVAL))
16                }
17            }
18            SYS_RMDIR => {
19                if let Some(path) = unsafe { str_from_raw_parts(packet.b as *const u8, packet.c) } {
20                    self.rmdir(path, packet.uid, packet.gid)
21                } else {
22                    Err(Error::new(EINVAL))
23                }
24            }
25            SYS_UNLINK => {
26                if let Some(path) = unsafe { str_from_raw_parts(packet.b as *const u8, packet.c) } {
27                    self.unlink(path, packet.uid, packet.gid)
28                } else {
29                    Err(Error::new(EINVAL))
30                }
31            }
32
33            SYS_DUP => convert_in_scheme_handle(
34                packet,
35                self.xdup(
36                    packet.b,
37                    unsafe { slice::from_raw_parts(packet.c as *const u8, packet.d) },
38                    &CallerCtx::from_packet(&packet),
39                ),
40            ),
41            SYS_READ => self.read(packet.b, unsafe {
42                slice::from_raw_parts_mut(packet.c as *mut u8, packet.d)
43            }),
44            SYS_WRITE => self.write(packet.b, unsafe {
45                slice::from_raw_parts(packet.c as *const u8, packet.d)
46            }),
47            SYS_LSEEK => self
48                .seek(packet.b, packet.c as isize, packet.d)
49                .map(|o| o as usize),
50            SYS_FCHMOD => self.fchmod(packet.b, packet.c as u16),
51            SYS_FCHOWN => self.fchown(packet.b, packet.c as u32, packet.d as u32),
52            SYS_FCNTL => self.fcntl(packet.b, packet.c, packet.d),
53            SYS_FEVENT => self
54                .fevent(packet.b, EventFlags::from_bits_truncate(packet.c))
55                .map(|f| f.bits()),
56            SYS_FPATH => self.fpath(packet.b, unsafe {
57                slice::from_raw_parts_mut(packet.c as *mut u8, packet.d)
58            }),
59            SYS_FRENAME => {
60                if let Some(path) = unsafe { str_from_raw_parts(packet.c as *const u8, packet.d) } {
61                    self.frename(packet.b, path, packet.uid, packet.gid)
62                } else {
63                    Err(Error::new(EINVAL))
64                }
65            }
66            SYS_FSTAT => {
67                if packet.d >= mem::size_of::<Stat>() {
68                    self.fstat(packet.b, unsafe { &mut *(packet.c as *mut Stat) })
69                } else {
70                    Err(Error::new(EFAULT))
71                }
72            }
73            SYS_FSTATVFS => {
74                if packet.d >= mem::size_of::<StatVfs>() {
75                    self.fstatvfs(packet.b, unsafe { &mut *(packet.c as *mut StatVfs) })
76                } else {
77                    Err(Error::new(EFAULT))
78                }
79            }
80            SYS_FSYNC => self.fsync(packet.b),
81            SYS_FTRUNCATE => self.ftruncate(packet.b, packet.c),
82            SYS_FUTIMENS => {
83                if packet.d >= mem::size_of::<TimeSpec>() {
84                    self.futimens(packet.b, unsafe {
85                        slice::from_raw_parts(
86                            packet.c as *const TimeSpec,
87                            packet.d / mem::size_of::<TimeSpec>(),
88                        )
89                    })
90                } else {
91                    Err(Error::new(EFAULT))
92                }
93            }
94            SYS_CLOSE => self.close(packet.b),
95
96            KSMSG_MMAP_PREP => self.mmap_prep(
97                packet.b,
98                u64::from(packet.uid) | (u64::from(packet.gid) << 32),
99                packet.c,
100                MapFlags::from_bits_truncate(packet.d),
101            ),
102            KSMSG_MUNMAP => self.munmap(
103                packet.b,
104                u64::from(packet.uid) | (u64::from(packet.gid) << 32),
105                packet.c,
106                MunmapFlags::from_bits_truncate(packet.d),
107            ),
108
109            _ => Err(Error::new(ENOSYS)),
110        };
111
112        packet.a = Error::mux(res);
113    }
114
115    /* Scheme operations */
116
117    #[allow(unused_variables)]
118    fn open(&self, path: &str, flags: usize, uid: u32, gid: u32) -> Result<usize> {
119        Err(Error::new(ENOENT))
120    }
121    #[allow(unused_variables)]
122    fn xopen(&self, path: &str, flags: usize, ctx: &CallerCtx) -> Result<OpenResult> {
123        convert_to_this_scheme(self.open(path, flags, ctx.uid, ctx.gid))
124    }
125
126    #[allow(unused_variables)]
127    fn chmod(&self, path: &str, mode: u16, uid: u32, gid: u32) -> Result<usize> {
128        Err(Error::new(ENOENT))
129    }
130
131    #[allow(unused_variables)]
132    fn rmdir(&self, path: &str, uid: u32, gid: u32) -> Result<usize> {
133        Err(Error::new(ENOENT))
134    }
135
136    #[allow(unused_variables)]
137    fn unlink(&self, path: &str, uid: u32, gid: u32) -> Result<usize> {
138        Err(Error::new(ENOENT))
139    }
140
141    /* Resource operations */
142    #[allow(unused_variables)]
143    fn dup(&self, old_id: usize, buf: &[u8]) -> Result<usize> {
144        Err(Error::new(EBADF))
145    }
146
147    #[allow(unused_variables)]
148    fn xdup(&self, old_id: usize, buf: &[u8], ctx: &CallerCtx) -> Result<OpenResult> {
149        convert_to_this_scheme(self.dup(old_id, buf))
150    }
151
152    #[allow(unused_variables)]
153    fn read(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
154        Err(Error::new(EBADF))
155    }
156
157    #[allow(unused_variables)]
158    fn write(&self, id: usize, buf: &[u8]) -> Result<usize> {
159        Err(Error::new(EBADF))
160    }
161
162    #[allow(unused_variables)]
163    fn seek(&self, id: usize, pos: isize, whence: usize) -> Result<isize> {
164        Err(Error::new(EBADF))
165    }
166
167    #[allow(unused_variables)]
168    fn fchmod(&self, id: usize, mode: u16) -> Result<usize> {
169        Err(Error::new(EBADF))
170    }
171
172    #[allow(unused_variables)]
173    fn fchown(&self, id: usize, uid: u32, gid: u32) -> Result<usize> {
174        Err(Error::new(EBADF))
175    }
176
177    #[allow(unused_variables)]
178    fn fcntl(&self, id: usize, cmd: usize, arg: usize) -> Result<usize> {
179        Err(Error::new(EBADF))
180    }
181
182    #[allow(unused_variables)]
183    fn fevent(&self, id: usize, flags: EventFlags) -> Result<EventFlags> {
184        Err(Error::new(EBADF))
185    }
186
187    #[allow(unused_variables)]
188    fn fpath(&self, id: usize, buf: &mut [u8]) -> Result<usize> {
189        Err(Error::new(EBADF))
190    }
191
192    #[allow(unused_variables)]
193    fn frename(&self, id: usize, path: &str, uid: u32, gid: u32) -> Result<usize> {
194        Err(Error::new(EBADF))
195    }
196
197    #[allow(unused_variables)]
198    fn fstat(&self, id: usize, stat: &mut Stat) -> Result<usize> {
199        Err(Error::new(EBADF))
200    }
201
202    #[allow(unused_variables)]
203    fn fstatvfs(&self, id: usize, stat: &mut StatVfs) -> Result<usize> {
204        Err(Error::new(EBADF))
205    }
206
207    #[allow(unused_variables)]
208    fn fsync(&self, id: usize) -> Result<usize> {
209        Err(Error::new(EBADF))
210    }
211
212    #[allow(unused_variables)]
213    fn ftruncate(&self, id: usize, len: usize) -> Result<usize> {
214        Err(Error::new(EBADF))
215    }
216
217    #[allow(unused_variables)]
218    fn futimens(&self, id: usize, times: &[TimeSpec]) -> Result<usize> {
219        Err(Error::new(EBADF))
220    }
221
222    #[allow(unused_variables)]
223    fn close(&self, id: usize) -> Result<usize> {
224        Err(Error::new(EBADF))
225    }
226
227    #[allow(unused_variables)]
228    fn mmap_prep(&self, id: usize, offset: u64, size: usize, flags: MapFlags) -> Result<usize> {
229        Err(Error::new(EOPNOTSUPP))
230    }
231
232    #[allow(unused_variables)]
233    fn munmap(&self, id: usize, offset: u64, size: usize, flags: MunmapFlags) -> Result<usize> {
234        Err(Error::new(EOPNOTSUPP))
235    }
236}