1818 */
1919
2020use aero_syscall:: prelude:: FdFlags ;
21- use aero_syscall:: { AeroSyscallError , OpenFlags } ;
21+ use aero_syscall:: { AeroSyscallError , OpenFlags , Stat } ;
2222
2323use crate :: fs:: inode:: DirEntry ;
2424use crate :: fs:: pipe:: Pipe ;
2525use crate :: fs:: { self , lookup_path, LookupMode } ;
26- use crate :: mem:: paging:: VirtAddr ;
2726use crate :: userland:: scheduler;
2827
2928use crate :: fs:: Path ;
30- use crate :: utils:: { validate_slice, validate_slice_mut, validate_str} ;
3129
32- pub fn write ( fd : usize , buffer : usize , size : usize ) -> Result < usize , AeroSyscallError > {
30+ #[ aero_proc:: syscall]
31+ pub fn write ( fd : usize , buffer : & [ u8 ] ) -> Result < usize , AeroSyscallError > {
3332 let handle = scheduler:: get_scheduler ( )
3433 . current_task ( )
3534 . file_table
@@ -40,14 +39,14 @@ pub fn write(fd: usize, buffer: usize, size: usize) -> Result<usize, AeroSyscall
4039 . flags
4140 . intersects ( OpenFlags :: O_WRONLY | OpenFlags :: O_RDWR )
4241 {
43- let buffer = validate_slice ( buffer as * const u8 , size) . ok_or ( AeroSyscallError :: EINVAL ) ?;
4442 Ok ( handle. write ( buffer) ?)
4543 } else {
4644 Err ( AeroSyscallError :: EACCES )
4745 }
4846}
4947
50- pub fn read ( fd : usize , buffer : usize , size : usize ) -> Result < usize , AeroSyscallError > {
48+ #[ aero_proc:: syscall]
49+ pub fn read ( fd : usize , buffer : & mut [ u8 ] ) -> Result < usize , AeroSyscallError > {
5150 let handle = scheduler:: get_scheduler ( )
5251 . current_task ( )
5352 . file_table
@@ -58,23 +57,20 @@ pub fn read(fd: usize, buffer: usize, size: usize) -> Result<usize, AeroSyscallE
5857 . flags
5958 . intersects ( OpenFlags :: O_RDONLY | OpenFlags :: O_RDWR )
6059 {
61- let buffer = validate_slice_mut ( buffer as * mut u8 , size) . ok_or ( AeroSyscallError :: EINVAL ) ?;
6260 Ok ( handle. read ( buffer) ?)
6361 } else {
6462 Err ( AeroSyscallError :: EACCES )
6563 }
6664}
6765
68- pub fn open ( _fd : usize , path : usize , len : usize , mode : usize ) -> Result < usize , AeroSyscallError > {
66+ #[ aero_proc:: syscall]
67+ pub fn open ( _fd : usize , path : & Path , mode : usize ) -> Result < usize , AeroSyscallError > {
6968 let mut flags = OpenFlags :: from_bits ( mode) . ok_or ( AeroSyscallError :: EINVAL ) ?;
7069
7170 if !flags. intersects ( OpenFlags :: O_RDONLY | OpenFlags :: O_RDWR | OpenFlags :: O_WRONLY ) {
7271 flags. insert ( OpenFlags :: O_RDONLY ) ;
7372 }
7473
75- let path = validate_str ( path as * const u8 , len) . ok_or ( AeroSyscallError :: EINVAL ) ?;
76- let path = Path :: new ( path) ;
77-
7874 let mut lookup_mode = LookupMode :: None ;
7975
8076 if flags. contains ( OpenFlags :: O_CREAT ) {
@@ -97,31 +93,34 @@ pub fn open(_fd: usize, path: usize, len: usize, mode: usize) -> Result<usize, A
9793 . open_file ( inode, flags) ?)
9894}
9995
96+ #[ aero_proc:: syscall]
10097pub fn dup ( fd : usize , flags : usize ) -> Result < usize , AeroSyscallError > {
10198 let task = scheduler:: get_scheduler ( ) . current_task ( ) ;
10299 let flags = OpenFlags :: from_bits ( flags) . ok_or ( AeroSyscallError :: EINVAL ) ? & OpenFlags :: O_CLOEXEC ;
103100
104101 task. file_table . duplicate ( fd, flags)
105102}
106103
104+ #[ aero_proc:: syscall]
107105pub fn dup2 ( fd : usize , new_fd : usize , flags : usize ) -> Result < usize , AeroSyscallError > {
108106 let task = scheduler:: get_scheduler ( ) . current_task ( ) ;
109107 let flags = OpenFlags :: from_bits ( flags) . ok_or ( AeroSyscallError :: EINVAL ) ? & OpenFlags :: O_CLOEXEC ;
110108
111109 task. file_table . duplicate_at ( fd, new_fd, flags)
112110}
113111
114- pub fn getdents ( fd : usize , buffer : usize , size : usize ) -> Result < usize , AeroSyscallError > {
112+ #[ aero_proc:: syscall]
113+ pub fn getdents ( fd : usize , buffer : & mut [ u8 ] ) -> Result < usize , AeroSyscallError > {
115114 let handle = scheduler:: get_scheduler ( )
116115 . current_task ( )
117116 . file_table
118117 . get_handle ( fd)
119118 . ok_or ( AeroSyscallError :: EBADFD ) ?;
120119
121- let buffer = validate_slice_mut ( buffer as * mut u8 , size) . ok_or ( AeroSyscallError :: EINVAL ) ?;
122120 Ok ( handle. get_dents ( buffer) ?)
123121}
124122
123+ #[ aero_proc:: syscall]
125124pub fn close ( fd : usize ) -> Result < usize , AeroSyscallError > {
126125 let res = scheduler:: get_scheduler ( )
127126 . current_task ( )
@@ -136,9 +135,9 @@ pub fn close(fd: usize) -> Result<usize, AeroSyscallError> {
136135 }
137136}
138137
139- pub fn chdir ( path : usize , size : usize ) -> Result < usize , AeroSyscallError > {
140- let buffer = validate_str ( path as * mut u8 , size ) . ok_or ( AeroSyscallError :: EINVAL ) ? ;
141- let inode = fs:: lookup_path ( Path :: new ( buffer ) ) ?;
138+ # [ aero_proc :: syscall ]
139+ pub fn chdir ( path : & str ) -> Result < usize , AeroSyscallError > {
140+ let inode = fs:: lookup_path ( Path :: new ( path ) ) ?;
142141
143142 if !inode. inode ( ) . metadata ( ) ?. is_directory ( ) {
144143 // A component of path is not a directory.
@@ -149,10 +148,8 @@ pub fn chdir(path: usize, size: usize) -> Result<usize, AeroSyscallError> {
149148 Ok ( 0x00 )
150149}
151150
152- pub fn mkdirat ( dfd : usize , path : usize , size : usize ) -> Result < usize , AeroSyscallError > {
153- let path_str = validate_str ( path as * mut u8 , size) . ok_or ( AeroSyscallError :: EINVAL ) ?;
154- let path = Path :: new ( path_str) ;
155-
151+ #[ aero_proc:: syscall]
152+ pub fn mkdirat ( dfd : usize , path : & Path ) -> Result < usize , AeroSyscallError > {
156153 // NOTE: If the pathname given in pathname is relative, then it is interpreted
157154 // relative to the directory referred to by the file descriptor (rather than relative
158155 // to the current working directory of the calling task, as is done by mkdir() for a
@@ -183,7 +180,7 @@ pub fn mkdirat(dfd: usize, path: usize, size: usize) -> Result<usize, AeroSyscal
183180 return Err ( AeroSyscallError :: ENOTDIR ) ;
184181 }
185182
186- if [ "" , "." , ".." ] . contains ( & path_str ) {
183+ if [ "" , "." , ".." ] . contains ( & path . as_str ( ) ) {
187184 // Cannot create a directory with a name of "", ".", or "..".
188185 return Err ( AeroSyscallError :: EEXIST ) ;
189186 }
@@ -192,14 +189,9 @@ pub fn mkdirat(dfd: usize, path: usize, size: usize) -> Result<usize, AeroSyscal
192189 Ok ( 0x00 )
193190}
194191
195- #[ inline]
196- pub fn mkdir ( path : usize , size : usize ) -> Result < usize , AeroSyscallError > {
197- mkdirat ( aero_syscall:: AT_FDCWD as _ , path, size)
198- }
199-
200- pub fn rmdir ( path : usize , size : usize ) -> Result < usize , AeroSyscallError > {
201- let path_str = validate_str ( path as * mut u8 , size) . ok_or ( AeroSyscallError :: EINVAL ) ?;
202- let path = Path :: new ( path_str) ;
192+ #[ aero_proc:: syscall]
193+ pub fn rmdir ( path : & str ) -> Result < usize , AeroSyscallError > {
194+ let path = Path :: new ( path) ;
203195
204196 let ( _, child) = path. parent_and_basename ( ) ;
205197 let inode = fs:: lookup_path ( path) ?;
@@ -215,20 +207,15 @@ pub fn rmdir(path: usize, size: usize) -> Result<usize, AeroSyscallError> {
215207 Ok ( 0x00 )
216208}
217209
218- pub fn getcwd ( buffer : usize , size : usize ) -> Result < usize , AeroSyscallError > {
219- // Invalid value of the size argument is zero and buffer is not a
220- // null pointer.
221- if size == 0x00 && buffer != 0x00 {
222- return Err ( AeroSyscallError :: EINVAL ) ;
223- }
224-
225- let buffer = validate_slice_mut ( buffer as * mut u8 , size) . ok_or ( AeroSyscallError :: EINVAL ) ?;
210+ #[ aero_proc:: syscall]
211+ pub fn getcwd ( buffer : & mut [ u8 ] ) -> Result < usize , AeroSyscallError > {
226212 let cwd = scheduler:: get_scheduler ( ) . current_task ( ) . get_cwd ( ) ;
227213
228214 buffer[ ..cwd. len ( ) ] . copy_from_slice ( cwd. as_bytes ( ) ) ;
229215 Ok ( cwd. len ( ) )
230216}
231217
218+ #[ aero_proc:: syscall]
232219pub fn ioctl ( fd : usize , command : usize , argument : usize ) -> Result < usize , AeroSyscallError > {
233220 let handle = scheduler:: get_scheduler ( )
234221 . current_task ( )
@@ -239,6 +226,7 @@ pub fn ioctl(fd: usize, command: usize, argument: usize) -> Result<usize, AeroSy
239226 Ok ( handle. inode ( ) . ioctl ( command, argument) ?)
240227}
241228
229+ #[ aero_proc:: syscall]
242230pub fn seek ( fd : usize , offset : usize , whence : usize ) -> Result < usize , AeroSyscallError > {
243231 let handle = scheduler:: get_scheduler ( )
244232 . current_task ( )
@@ -249,10 +237,11 @@ pub fn seek(fd: usize, offset: usize, whence: usize) -> Result<usize, AeroSyscal
249237 Ok ( handle. seek ( offset as isize , aero_syscall:: SeekWhence :: from ( whence) ) ?)
250238}
251239
252- pub fn pipe ( fds : usize , flags : usize ) -> Result < usize , AeroSyscallError > {
253- let flags = OpenFlags :: from_bits ( flags ) . ok_or ( AeroSyscallError :: EINVAL ) ? ;
254- let fds = validate_slice_mut ( fds as * mut usize , 2 ) . ok_or ( AeroSyscallError :: EINVAL ) ? ;
240+ # [ aero_proc :: syscall ]
241+ pub fn pipe ( fds : & mut [ usize ] , flags : usize ) -> Result < usize , AeroSyscallError > {
242+ assert ! ( fds. len ( ) == 2 ) ;
255243
244+ let flags = OpenFlags :: from_bits ( flags) . ok_or ( AeroSyscallError :: EINVAL ) ?;
256245 let pipe = Pipe :: new ( ) ;
257246
258247 let entry = DirEntry :: from_inode ( pipe) ;
@@ -282,15 +271,8 @@ pub fn pipe(fds: usize, flags: usize) -> Result<usize, AeroSyscallError> {
282271 Ok ( 0x00 )
283272}
284273
285- pub fn unlink (
286- fd : usize ,
287- path : usize ,
288- path_size : usize ,
289- flags : usize ,
290- ) -> Result < usize , AeroSyscallError > {
291- let path_str = validate_str ( path as * mut u8 , path_size) . ok_or ( AeroSyscallError :: EINVAL ) ?;
292- let path = Path :: new ( path_str) ;
293-
274+ #[ aero_proc:: syscall]
275+ pub fn unlink ( fd : usize , path : & Path , flags : usize ) -> Result < usize , AeroSyscallError > {
294276 // TODO: Make use of the open flags.
295277 let _flags = OpenFlags :: from_bits ( flags) . ok_or ( AeroSyscallError :: EINVAL ) ?;
296278 let name = path. container ( ) ;
@@ -313,16 +295,13 @@ pub fn unlink(
313295 Ok ( 0x00 )
314296}
315297
298+ #[ aero_proc:: syscall]
316299pub fn access (
317300 fd : usize ,
318- path : usize ,
319- path_size : usize ,
301+ path : & Path ,
320302 _mode : usize ,
321303 _flags : usize ,
322304) -> Result < usize , AeroSyscallError > {
323- let path_str = validate_str ( path as * mut u8 , path_size) . ok_or ( AeroSyscallError :: EINVAL ) ?;
324- let path = Path :: new ( path_str) ;
325-
326305 if fd as isize == aero_syscall:: AT_FDCWD {
327306 lookup_path ( path) ?;
328307 Ok ( 0x00 )
@@ -332,6 +311,7 @@ pub fn access(
332311 }
333312}
334313
314+ #[ aero_proc:: syscall]
335315pub fn fcntl ( fd : usize , command : usize , arg : usize ) -> Result < usize , AeroSyscallError > {
336316 let handle = scheduler:: get_scheduler ( )
337317 . current_task ( )
@@ -364,50 +344,31 @@ pub fn fcntl(fd: usize, command: usize, arg: usize) -> Result<usize, AeroSyscall
364344 }
365345}
366346
367- /// Validates the [`aero_syscall::Stat`] struct provided by the user and returns a mutable
368- /// reference to it. [`AeroSyscallError::EFAULT`] is returned if the provided pointer is outside
369- /// of the user's address space.
370- fn validate_stat_struct < ' struc > (
371- stat_struct : usize ,
372- ) -> Result < & ' struc mut aero_syscall:: Stat , AeroSyscallError > {
373- VirtAddr :: new ( stat_struct as _ )
374- . read_mut :: < aero_syscall:: Stat > ( )
375- . ok_or ( AeroSyscallError :: EFAULT )
376- }
377-
378- pub fn fstat ( fd : usize , stat_struct : usize ) -> Result < usize , AeroSyscallError > {
379- let stat_struct = validate_stat_struct ( stat_struct) ?;
380- let handle = scheduler:: get_scheduler ( )
347+ #[ aero_proc:: syscall]
348+ pub fn fstat ( fd : usize , stat : & mut Stat ) -> Result < usize , AeroSyscallError > {
349+ let file = scheduler:: get_scheduler ( )
381350 . current_task ( )
382351 . file_table
383352 . get_handle ( fd)
384353 . ok_or ( AeroSyscallError :: EBADFD ) ?;
385354
386- * stat_struct = handle. inode ( ) . stat ( ) ?;
355+ * stat = file. inode ( ) . stat ( ) ?;
356+
387357 Ok ( 0 )
388358}
389359
390- pub fn stat ( path : usize , path_size : usize , stat_struct : usize ) -> Result < usize , AeroSyscallError > {
391- let stat_struct = validate_stat_struct ( stat_struct) ?;
392-
393- let path = validate_str ( path as * mut u8 , path_size) . ok_or ( AeroSyscallError :: EINVAL ) ?;
394- let path = Path :: new ( path) ;
395-
360+ #[ aero_proc:: syscall]
361+ pub fn stat ( path : & Path , stat : & mut Stat ) -> Result < usize , AeroSyscallError > {
396362 let file = fs:: lookup_path ( path) ?;
397- * stat_struct = file. inode ( ) . stat ( ) ?;
363+
364+ * stat = file. inode ( ) . stat ( ) ?;
398365
399366 Ok ( 0 )
400367}
401368
402- pub fn read_link (
403- path : usize ,
404- path_size : usize ,
405- _buffer : usize ,
406- _buffer_size : usize ,
407- ) -> Result < usize , AeroSyscallError > {
408- let path = validate_str ( path as * mut u8 , path_size) . ok_or ( AeroSyscallError :: EINVAL ) ?;
409- let path = Path :: new ( path) ;
410-
369+ #[ aero_proc:: syscall]
370+ pub fn read_link ( path : & Path , _buffer : & mut [ u8 ] ) -> Result < usize , AeroSyscallError > {
411371 log:: warn!( "read_link: is a stub! (path={path:?})" ) ;
372+
412373 Err ( AeroSyscallError :: EINVAL )
413374}
0 commit comments