18
18
*/
19
19
20
20
use aero_syscall:: prelude:: FdFlags ;
21
- use aero_syscall:: { AeroSyscallError , OpenFlags } ;
21
+ use aero_syscall:: { AeroSyscallError , OpenFlags , Stat } ;
22
22
23
23
use crate :: fs:: inode:: DirEntry ;
24
24
use crate :: fs:: pipe:: Pipe ;
25
25
use crate :: fs:: { self , lookup_path, LookupMode } ;
26
- use crate :: mem:: paging:: VirtAddr ;
27
26
use crate :: userland:: scheduler;
28
27
29
28
use crate :: fs:: Path ;
30
- use crate :: utils:: { validate_slice, validate_slice_mut, validate_str} ;
31
29
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 > {
33
32
let handle = scheduler:: get_scheduler ( )
34
33
. current_task ( )
35
34
. file_table
@@ -40,14 +39,14 @@ pub fn write(fd: usize, buffer: usize, size: usize) -> Result<usize, AeroSyscall
40
39
. flags
41
40
. intersects ( OpenFlags :: O_WRONLY | OpenFlags :: O_RDWR )
42
41
{
43
- let buffer = validate_slice ( buffer as * const u8 , size) . ok_or ( AeroSyscallError :: EINVAL ) ?;
44
42
Ok ( handle. write ( buffer) ?)
45
43
} else {
46
44
Err ( AeroSyscallError :: EACCES )
47
45
}
48
46
}
49
47
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 > {
51
50
let handle = scheduler:: get_scheduler ( )
52
51
. current_task ( )
53
52
. file_table
@@ -58,23 +57,20 @@ pub fn read(fd: usize, buffer: usize, size: usize) -> Result<usize, AeroSyscallE
58
57
. flags
59
58
. intersects ( OpenFlags :: O_RDONLY | OpenFlags :: O_RDWR )
60
59
{
61
- let buffer = validate_slice_mut ( buffer as * mut u8 , size) . ok_or ( AeroSyscallError :: EINVAL ) ?;
62
60
Ok ( handle. read ( buffer) ?)
63
61
} else {
64
62
Err ( AeroSyscallError :: EACCES )
65
63
}
66
64
}
67
65
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 > {
69
68
let mut flags = OpenFlags :: from_bits ( mode) . ok_or ( AeroSyscallError :: EINVAL ) ?;
70
69
71
70
if !flags. intersects ( OpenFlags :: O_RDONLY | OpenFlags :: O_RDWR | OpenFlags :: O_WRONLY ) {
72
71
flags. insert ( OpenFlags :: O_RDONLY ) ;
73
72
}
74
73
75
- let path = validate_str ( path as * const u8 , len) . ok_or ( AeroSyscallError :: EINVAL ) ?;
76
- let path = Path :: new ( path) ;
77
-
78
74
let mut lookup_mode = LookupMode :: None ;
79
75
80
76
if flags. contains ( OpenFlags :: O_CREAT ) {
@@ -97,31 +93,34 @@ pub fn open(_fd: usize, path: usize, len: usize, mode: usize) -> Result<usize, A
97
93
. open_file ( inode, flags) ?)
98
94
}
99
95
96
+ #[ aero_proc:: syscall]
100
97
pub fn dup ( fd : usize , flags : usize ) -> Result < usize , AeroSyscallError > {
101
98
let task = scheduler:: get_scheduler ( ) . current_task ( ) ;
102
99
let flags = OpenFlags :: from_bits ( flags) . ok_or ( AeroSyscallError :: EINVAL ) ? & OpenFlags :: O_CLOEXEC ;
103
100
104
101
task. file_table . duplicate ( fd, flags)
105
102
}
106
103
104
+ #[ aero_proc:: syscall]
107
105
pub fn dup2 ( fd : usize , new_fd : usize , flags : usize ) -> Result < usize , AeroSyscallError > {
108
106
let task = scheduler:: get_scheduler ( ) . current_task ( ) ;
109
107
let flags = OpenFlags :: from_bits ( flags) . ok_or ( AeroSyscallError :: EINVAL ) ? & OpenFlags :: O_CLOEXEC ;
110
108
111
109
task. file_table . duplicate_at ( fd, new_fd, flags)
112
110
}
113
111
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 > {
115
114
let handle = scheduler:: get_scheduler ( )
116
115
. current_task ( )
117
116
. file_table
118
117
. get_handle ( fd)
119
118
. ok_or ( AeroSyscallError :: EBADFD ) ?;
120
119
121
- let buffer = validate_slice_mut ( buffer as * mut u8 , size) . ok_or ( AeroSyscallError :: EINVAL ) ?;
122
120
Ok ( handle. get_dents ( buffer) ?)
123
121
}
124
122
123
+ #[ aero_proc:: syscall]
125
124
pub fn close ( fd : usize ) -> Result < usize , AeroSyscallError > {
126
125
let res = scheduler:: get_scheduler ( )
127
126
. current_task ( )
@@ -136,9 +135,9 @@ pub fn close(fd: usize) -> Result<usize, AeroSyscallError> {
136
135
}
137
136
}
138
137
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 ) ) ?;
142
141
143
142
if !inode. inode ( ) . metadata ( ) ?. is_directory ( ) {
144
143
// A component of path is not a directory.
@@ -149,10 +148,8 @@ pub fn chdir(path: usize, size: usize) -> Result<usize, AeroSyscallError> {
149
148
Ok ( 0x00 )
150
149
}
151
150
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 > {
156
153
// NOTE: If the pathname given in pathname is relative, then it is interpreted
157
154
// relative to the directory referred to by the file descriptor (rather than relative
158
155
// 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
183
180
return Err ( AeroSyscallError :: ENOTDIR ) ;
184
181
}
185
182
186
- if [ "" , "." , ".." ] . contains ( & path_str ) {
183
+ if [ "" , "." , ".." ] . contains ( & path . as_str ( ) ) {
187
184
// Cannot create a directory with a name of "", ".", or "..".
188
185
return Err ( AeroSyscallError :: EEXIST ) ;
189
186
}
@@ -192,14 +189,9 @@ pub fn mkdirat(dfd: usize, path: usize, size: usize) -> Result<usize, AeroSyscal
192
189
Ok ( 0x00 )
193
190
}
194
191
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) ;
203
195
204
196
let ( _, child) = path. parent_and_basename ( ) ;
205
197
let inode = fs:: lookup_path ( path) ?;
@@ -215,20 +207,15 @@ pub fn rmdir(path: usize, size: usize) -> Result<usize, AeroSyscallError> {
215
207
Ok ( 0x00 )
216
208
}
217
209
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 > {
226
212
let cwd = scheduler:: get_scheduler ( ) . current_task ( ) . get_cwd ( ) ;
227
213
228
214
buffer[ ..cwd. len ( ) ] . copy_from_slice ( cwd. as_bytes ( ) ) ;
229
215
Ok ( cwd. len ( ) )
230
216
}
231
217
218
+ #[ aero_proc:: syscall]
232
219
pub fn ioctl ( fd : usize , command : usize , argument : usize ) -> Result < usize , AeroSyscallError > {
233
220
let handle = scheduler:: get_scheduler ( )
234
221
. current_task ( )
@@ -239,6 +226,7 @@ pub fn ioctl(fd: usize, command: usize, argument: usize) -> Result<usize, AeroSy
239
226
Ok ( handle. inode ( ) . ioctl ( command, argument) ?)
240
227
}
241
228
229
+ #[ aero_proc:: syscall]
242
230
pub fn seek ( fd : usize , offset : usize , whence : usize ) -> Result < usize , AeroSyscallError > {
243
231
let handle = scheduler:: get_scheduler ( )
244
232
. current_task ( )
@@ -249,10 +237,11 @@ pub fn seek(fd: usize, offset: usize, whence: usize) -> Result<usize, AeroSyscal
249
237
Ok ( handle. seek ( offset as isize , aero_syscall:: SeekWhence :: from ( whence) ) ?)
250
238
}
251
239
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 ) ;
255
243
244
+ let flags = OpenFlags :: from_bits ( flags) . ok_or ( AeroSyscallError :: EINVAL ) ?;
256
245
let pipe = Pipe :: new ( ) ;
257
246
258
247
let entry = DirEntry :: from_inode ( pipe) ;
@@ -282,15 +271,8 @@ pub fn pipe(fds: usize, flags: usize) -> Result<usize, AeroSyscallError> {
282
271
Ok ( 0x00 )
283
272
}
284
273
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 > {
294
276
// TODO: Make use of the open flags.
295
277
let _flags = OpenFlags :: from_bits ( flags) . ok_or ( AeroSyscallError :: EINVAL ) ?;
296
278
let name = path. container ( ) ;
@@ -313,16 +295,13 @@ pub fn unlink(
313
295
Ok ( 0x00 )
314
296
}
315
297
298
+ #[ aero_proc:: syscall]
316
299
pub fn access (
317
300
fd : usize ,
318
- path : usize ,
319
- path_size : usize ,
301
+ path : & Path ,
320
302
_mode : usize ,
321
303
_flags : usize ,
322
304
) -> 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
-
326
305
if fd as isize == aero_syscall:: AT_FDCWD {
327
306
lookup_path ( path) ?;
328
307
Ok ( 0x00 )
@@ -332,6 +311,7 @@ pub fn access(
332
311
}
333
312
}
334
313
314
+ #[ aero_proc:: syscall]
335
315
pub fn fcntl ( fd : usize , command : usize , arg : usize ) -> Result < usize , AeroSyscallError > {
336
316
let handle = scheduler:: get_scheduler ( )
337
317
. current_task ( )
@@ -364,50 +344,31 @@ pub fn fcntl(fd: usize, command: usize, arg: usize) -> Result<usize, AeroSyscall
364
344
}
365
345
}
366
346
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 ( )
381
350
. current_task ( )
382
351
. file_table
383
352
. get_handle ( fd)
384
353
. ok_or ( AeroSyscallError :: EBADFD ) ?;
385
354
386
- * stat_struct = handle. inode ( ) . stat ( ) ?;
355
+ * stat = file. inode ( ) . stat ( ) ?;
356
+
387
357
Ok ( 0 )
388
358
}
389
359
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 > {
396
362
let file = fs:: lookup_path ( path) ?;
397
- * stat_struct = file. inode ( ) . stat ( ) ?;
363
+
364
+ * stat = file. inode ( ) . stat ( ) ?;
398
365
399
366
Ok ( 0 )
400
367
}
401
368
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 > {
411
371
log:: warn!( "read_link: is a stub! (path={path:?})" ) ;
372
+
412
373
Err ( AeroSyscallError :: EINVAL )
413
374
}
0 commit comments