15
15
// You should have received a copy of the GNU General Public License
16
16
// along with Aero. If not, see <https://www.gnu.org/licenses/>.
17
17
18
+ use core:: fmt;
19
+
18
20
use aero_syscall:: prelude:: * ;
19
21
use aero_syscall:: signal:: SigProcMask ;
20
22
use aero_syscall:: { OpenFlags , Stat , SyscallError , TimeSpec , AT_FDCWD } ;
23
+ use alloc:: sync:: Arc ;
21
24
22
25
use crate :: fs:: cache:: { self , DirCacheImpl } ;
23
26
use crate :: fs:: epoll:: EPoll ;
24
27
use crate :: fs:: eventfd:: EventFd ;
25
- use crate :: fs:: file_table:: DuplicateHint ;
28
+ use crate :: fs:: file_table:: { DuplicateHint , FileHandle } ;
26
29
use crate :: fs:: inode:: { DirEntry , PollTable } ;
27
30
use crate :: fs:: pipe:: Pipe ;
28
31
use crate :: fs:: { self , lookup_path, LookupMode } ;
29
32
use crate :: userland:: scheduler;
30
33
31
34
use crate :: fs:: Path ;
32
35
33
- #[ syscall]
34
- pub fn write ( fd : usize , buffer : & [ u8 ] ) -> Result < usize , SyscallError > {
35
- let handle = scheduler:: get_scheduler ( )
36
- . current_task ( )
37
- . file_table
38
- . get_handle ( fd)
39
- . ok_or ( SyscallError :: EBADFD ) ?;
36
+ #[ derive( Debug , Copy , Clone ) ]
37
+ pub struct FileDescriptor ( usize ) ;
38
+
39
+ impl FileDescriptor {
40
+ /// Returns the file handle associated with this file descriptor.
41
+ ///
42
+ /// ## Errors
43
+ /// * `EBADFD`: The file descriptor is not a valid open file descriptor.
44
+ pub fn handle ( & self ) -> aero_syscall:: Result < Arc < FileHandle > > {
45
+ scheduler:: current_thread ( )
46
+ . file_table
47
+ . get_handle ( self . 0 )
48
+ . ok_or ( SyscallError :: EBADFD )
49
+ }
50
+ }
51
+
52
+ impl fmt:: Display for FileDescriptor {
53
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
54
+ if let Ok ( file_handle) = self . handle ( ) {
55
+ let path = file_handle. inode . absolute_path_str ( ) ;
56
+ write ! ( f, "{{ {} -> {} }}" , self . 0 , path)
57
+ } else {
58
+ // invalid file descriptor
59
+ write ! ( f, "{{ {} -> INVALID }}" , self . 0 )
60
+ }
61
+ }
62
+ }
40
63
64
+ impl super :: SysArg for FileDescriptor {
65
+ fn from_usize ( value : usize ) -> Self {
66
+ Self ( value)
67
+ }
68
+ }
69
+
70
+ impl Into < usize > for FileDescriptor {
71
+ fn into ( self ) -> usize {
72
+ self . 0
73
+ }
74
+ }
75
+
76
+ #[ syscall]
77
+ pub fn write ( fd : FileDescriptor , buffer : & [ u8 ] ) -> Result < usize , SyscallError > {
41
78
// FIXME(heck for xeyes): fnctl should update the open flags!
42
79
//
43
80
// if handle
44
81
// .flags
45
82
// .intersects(OpenFlags::O_WRONLY | OpenFlags::O_RDWR)
46
83
// {
47
- Ok ( handle. write ( buffer) ?)
84
+ Ok ( fd . handle ( ) ? . write ( buffer) ?)
48
85
// } else {
49
86
// Err(SyscallError::EACCES)
50
87
// }
51
88
}
52
89
53
90
#[ syscall]
54
- pub fn read ( fd : usize , buffer : & mut [ u8 ] ) -> Result < usize , SyscallError > {
55
- let handle = scheduler:: get_scheduler ( )
56
- . current_task ( )
57
- . file_table
58
- . get_handle ( fd)
59
- . ok_or ( SyscallError :: EBADFD ) ?;
60
-
91
+ pub fn read ( fd : FileDescriptor , buffer : & mut [ u8 ] ) -> Result < usize , SyscallError > {
61
92
// if handle
62
93
// .flags
63
94
// .read()
64
95
// .intersects(OpenFlags::O_RDONLY | OpenFlags::O_RDWR)
65
96
// {
66
- Ok ( handle. read ( buffer) ?)
97
+ Ok ( fd . handle ( ) ? . read ( buffer) ?)
67
98
// } else {
68
99
// Err(SyscallError::EACCES)
69
100
// }
@@ -111,42 +142,37 @@ pub fn open(fd: usize, path: &Path, mode: usize) -> Result<usize, SyscallError>
111
142
}
112
143
113
144
#[ syscall]
114
- pub fn dup ( fd : usize , flags : usize ) -> Result < usize , SyscallError > {
145
+ pub fn dup ( fd : FileDescriptor , flags : usize ) -> Result < usize , SyscallError > {
115
146
let task = scheduler:: get_scheduler ( ) . current_task ( ) ;
116
147
let flags = OpenFlags :: from_bits ( flags) . ok_or ( SyscallError :: EINVAL ) ? & OpenFlags :: O_CLOEXEC ;
117
148
118
- task. file_table . duplicate ( fd, DuplicateHint :: Any , flags)
149
+ task. file_table
150
+ . duplicate ( fd. into ( ) , DuplicateHint :: Any , flags)
119
151
}
120
152
121
153
#[ syscall]
122
- pub fn dup2 ( fd : usize , new_fd : usize , flags : usize ) -> Result < usize , SyscallError > {
154
+ pub fn dup2 ( fd : FileDescriptor , new_fd : usize , flags : usize ) -> Result < usize , SyscallError > {
123
155
let task = scheduler:: get_scheduler ( ) . current_task ( ) ;
124
156
let flags = OpenFlags :: from_bits ( flags) . ok_or ( SyscallError :: EINVAL ) ? & OpenFlags :: O_CLOEXEC ;
125
157
126
158
task. file_table
127
- . duplicate ( fd, DuplicateHint :: Exact ( new_fd) , flags)
159
+ . duplicate ( fd. into ( ) , DuplicateHint :: Exact ( new_fd) , flags)
128
160
}
129
161
130
162
#[ syscall]
131
- pub fn getdents ( fd : usize , buffer : & mut [ u8 ] ) -> Result < usize , SyscallError > {
132
- let handle = scheduler:: get_scheduler ( )
133
- . current_task ( )
134
- . file_table
135
- . get_handle ( fd)
136
- . ok_or ( SyscallError :: EBADFD ) ?;
137
-
138
- Ok ( handle. get_dents ( buffer) ?)
163
+ pub fn getdents ( fd : FileDescriptor , buffer : & mut [ u8 ] ) -> Result < usize , SyscallError > {
164
+ Ok ( fd. handle ( ) ?. get_dents ( buffer) ?)
139
165
}
140
166
141
167
#[ syscall]
142
- pub fn close ( fd : usize ) -> Result < usize , SyscallError > {
168
+ pub fn close ( fd : FileDescriptor ) -> Result < usize , SyscallError > {
143
169
let res = scheduler:: get_scheduler ( )
144
170
. current_task ( )
145
171
. file_table
146
- . close_file ( fd) ;
172
+ . close_file ( fd. into ( ) ) ;
147
173
148
174
if res {
149
- Ok ( 0x00 )
175
+ Ok ( 0 )
150
176
} else {
151
177
// FD isn't a valid open file descriptor.
152
178
Err ( SyscallError :: EBADFD )
@@ -163,7 +189,7 @@ pub fn chdir(path: &str) -> Result<usize, SyscallError> {
163
189
}
164
190
165
191
scheduler:: get_scheduler ( ) . current_task ( ) . set_cwd ( inode) ;
166
- Ok ( 0x00 )
192
+ Ok ( 0 )
167
193
}
168
194
169
195
#[ syscall]
@@ -234,12 +260,8 @@ pub fn getcwd(buffer: &mut [u8]) -> Result<usize, SyscallError> {
234
260
}
235
261
236
262
#[ syscall]
237
- pub fn ioctl ( fd : usize , command : usize , argument : usize ) -> Result < usize , SyscallError > {
238
- let handle = scheduler:: get_scheduler ( )
239
- . current_task ( )
240
- . file_table
241
- . get_handle ( fd)
242
- . ok_or ( SyscallError :: EBADFD ) ?;
263
+ pub fn ioctl ( fd : FileDescriptor , command : usize , argument : usize ) -> Result < usize , SyscallError > {
264
+ let handle = fd. handle ( ) ?;
243
265
244
266
match command {
245
267
// Sets the close-on-exec file descriptor flag. This is equivalent
@@ -262,13 +284,8 @@ pub fn ioctl(fd: usize, command: usize, argument: usize) -> Result<usize, Syscal
262
284
}
263
285
264
286
#[ syscall]
265
- pub fn seek ( fd : usize , offset : usize , whence : usize ) -> Result < usize , SyscallError > {
266
- let handle = scheduler:: get_scheduler ( )
267
- . current_task ( )
268
- . file_table
269
- . get_handle ( fd)
270
- . ok_or ( SyscallError :: EBADFD ) ?;
271
-
287
+ pub fn seek ( fd : FileDescriptor , offset : usize , whence : usize ) -> Result < usize , SyscallError > {
288
+ let handle = fd. handle ( ) ?;
272
289
Ok ( handle. seek ( offset as isize , aero_syscall:: SeekWhence :: from ( whence) ) ?)
273
290
}
274
291
@@ -347,12 +364,8 @@ const SETFL_MASK: OpenFlags = OpenFlags::from_bits_truncate(
347
364
) ;
348
365
349
366
#[ syscall]
350
- pub fn fcntl ( fd : usize , command : usize , arg : usize ) -> Result < usize , SyscallError > {
351
- let handle = scheduler:: get_scheduler ( )
352
- . current_task ( )
353
- . file_table
354
- . get_handle ( fd)
355
- . ok_or ( SyscallError :: EBADFD ) ?;
367
+ pub fn fcntl ( fd : FileDescriptor , command : usize , arg : usize ) -> Result < usize , SyscallError > {
368
+ let handle = fd. handle ( ) ?;
356
369
357
370
match command {
358
371
// F_DUPFD_CLOEXEC and F_DUPFD:
@@ -364,19 +377,17 @@ pub fn fcntl(fd: usize, command: usize, arg: usize) -> Result<usize, SyscallErro
364
377
//
365
378
// F_DUPFD_CLOEXEC additionally sets the close-on-exec flag for the duplicate
366
379
// file descriptor.
367
- aero_syscall:: prelude:: F_DUPFD => scheduler:: get_scheduler ( )
368
- . current_task ( )
369
- . file_table
370
- . duplicate ( fd, DuplicateHint :: GreatorOrEqual ( arg) , handle. flags ( ) ) ,
371
-
372
- aero_syscall:: prelude:: F_DUPFD_CLOEXEC => scheduler:: get_scheduler ( )
373
- . current_task ( )
374
- . file_table
375
- . duplicate (
376
- fd,
377
- DuplicateHint :: GreatorOrEqual ( arg) ,
378
- handle. flags ( ) | OpenFlags :: O_CLOEXEC ,
379
- ) ,
380
+ aero_syscall:: prelude:: F_DUPFD => scheduler:: current_thread ( ) . file_table . duplicate (
381
+ fd. into ( ) ,
382
+ DuplicateHint :: GreatorOrEqual ( arg) ,
383
+ handle. flags ( ) ,
384
+ ) ,
385
+
386
+ aero_syscall:: prelude:: F_DUPFD_CLOEXEC => scheduler:: current_thread ( ) . file_table . duplicate (
387
+ fd. into ( ) ,
388
+ DuplicateHint :: GreatorOrEqual ( arg) ,
389
+ handle. flags ( ) | OpenFlags :: O_CLOEXEC ,
390
+ ) ,
380
391
381
392
// Get the value of file descriptor flags.
382
393
aero_syscall:: prelude:: F_GETFD => {
@@ -429,24 +440,15 @@ pub fn fcntl(fd: usize, command: usize, arg: usize) -> Result<usize, SyscallErro
429
440
}
430
441
431
442
#[ syscall]
432
- pub fn fstat ( fd : usize , stat : & mut Stat ) -> Result < usize , SyscallError > {
433
- let file = scheduler:: get_scheduler ( )
434
- . current_task ( )
435
- . file_table
436
- . get_handle ( fd)
437
- . ok_or ( SyscallError :: EBADFD ) ?;
438
-
439
- * stat = file. inode ( ) . stat ( ) ?;
440
-
443
+ pub fn fstat ( fd : FileDescriptor , stat : & mut Stat ) -> Result < usize , SyscallError > {
444
+ * stat = fd. handle ( ) ?. inode ( ) . stat ( ) ?;
441
445
Ok ( 0 )
442
446
}
443
447
444
448
#[ syscall]
445
449
pub fn stat ( path : & Path , stat : & mut Stat ) -> Result < usize , SyscallError > {
446
450
let file = fs:: lookup_path ( path) ?;
447
-
448
451
* stat = file. inode ( ) . stat ( ) ?;
449
-
450
452
Ok ( 0 )
451
453
}
452
454
@@ -480,16 +482,12 @@ pub fn epoll_create(flags: usize) -> Result<usize, SyscallError> {
480
482
/// the operation be performed for the target file descriptor.
481
483
#[ syscall]
482
484
pub fn epoll_ctl (
483
- epfd : usize ,
485
+ epfd : FileDescriptor ,
484
486
mode : usize ,
485
487
fd : usize ,
486
488
event : & mut EPollEvent ,
487
489
) -> Result < usize , SyscallError > {
488
- let epfd = scheduler:: get_scheduler ( )
489
- . current_task ( )
490
- . file_table
491
- . get_handle ( epfd)
492
- . ok_or ( SyscallError :: EBADFD ) ?;
490
+ let epfd = epfd. handle ( ) ?;
493
491
494
492
let epoll = epfd
495
493
. inode ( )
@@ -518,7 +516,7 @@ pub fn epoll_ctl(
518
516
519
517
#[ syscall]
520
518
pub fn epoll_pwait (
521
- epfd : usize ,
519
+ epfd : FileDescriptor ,
522
520
event : & mut [ EPollEvent ] ,
523
521
timeout : usize ,
524
522
sigmask : usize ,
@@ -528,11 +526,7 @@ pub fn epoll_pwait(
528
526
let current_task = scheduler:: get_scheduler ( ) . current_task ( ) ;
529
527
let signals = current_task. signals ( ) ;
530
528
531
- let epfd = current_task
532
- . file_table
533
- . get_handle ( epfd)
534
- . ok_or ( SyscallError :: EBADFD ) ?;
535
-
529
+ let epfd = epfd. handle ( ) ?;
536
530
let epfd = epfd
537
531
. inode ( )
538
532
. downcast_arc :: < EPoll > ( )
0 commit comments