@@ -13,7 +13,7 @@ use crate::env;
13
13
use crate :: errno:: * ;
14
14
use crate :: fd:: file:: { GenericFile , UhyveFile } ;
15
15
use crate :: fd:: stdio:: * ;
16
- use crate :: syscalls:: fs:: { self , FilePerms , SeekWhence } ;
16
+ use crate :: syscalls:: fs:: { self , Dirent , FileAttr , FilePerms , SeekWhence } ;
17
17
#[ cfg( all( any( feature = "tcp" , feature = "udp" ) , not( feature = "newlib" ) ) ) ]
18
18
use crate :: syscalls:: net:: * ;
19
19
@@ -181,6 +181,13 @@ fn open_flags_to_perm(flags: i32, mode: u32) -> FilePerms {
181
181
perms
182
182
}
183
183
184
+ #[ derive( Copy , Clone , Debug ) ]
185
+ #[ repr( C ) ]
186
+ pub enum DirectoryEntry {
187
+ Invalid ( i32 ) ,
188
+ Valid ( * const Dirent ) ,
189
+ }
190
+
184
191
pub trait ObjectInterface : Sync + Send + core:: fmt:: Debug + DynClone {
185
192
/// `read` attempts to read `len` bytes from the object references
186
193
/// by the descriptor
@@ -199,11 +206,33 @@ pub trait ObjectInterface: Sync + Send + core::fmt::Debug + DynClone {
199
206
( -EINVAL ) . try_into ( ) . unwrap ( )
200
207
}
201
208
202
- /// `unlink` removes directory entry
209
+ /// `fstat`
210
+ fn fstat ( & self , _stat : * mut FileAttr ) -> i32 {
211
+ -EINVAL
212
+ }
213
+
214
+ /// `unlink` removes file entry
203
215
fn unlink ( & self , _name : * const u8 ) -> i32 {
204
216
-EINVAL
205
217
}
206
218
219
+ /// `rmdir` removes directory entry
220
+ fn rmdir ( & self , _name : * const u8 ) -> i32 {
221
+ -EINVAL
222
+ }
223
+
224
+ /// 'readdir' returns a pointer to a dirent structure
225
+ /// representing the next directory entry in the directory stream
226
+ /// pointed to by the file descriptor
227
+ fn readdir ( & self ) -> DirectoryEntry {
228
+ DirectoryEntry :: Invalid ( -ENOSYS )
229
+ }
230
+
231
+ /// `mkdir` creates a directory entry
232
+ fn mkdir ( & self , _name : * const u8 , _mode : u32 ) -> i32 {
233
+ -EINVAL
234
+ }
235
+
207
236
/// `accept` a connection on a socket
208
237
#[ cfg( all( any( feature = "tcp" , feature = "udp" ) , not( feature = "newlib" ) ) ) ]
209
238
fn accept ( & self , _addr : * mut sockaddr , _addrlen : * mut socklen_t ) -> i32 {
@@ -319,6 +348,37 @@ pub(crate) fn open(name: *const u8, flags: i32, mode: i32) -> Result<FileDescrip
319
348
}
320
349
}
321
350
351
+ #[ allow( unused_variables) ]
352
+ pub ( crate ) fn opendir ( name : * const u8 ) -> Result < FileDescriptor , i32 > {
353
+ if env:: is_uhyve ( ) {
354
+ Err ( -EINVAL )
355
+ } else {
356
+ #[ cfg( target_arch = "x86_64" ) ]
357
+ {
358
+ let name = unsafe { CStr :: from_ptr ( name as _ ) } . to_str ( ) . unwrap ( ) ;
359
+ debug ! ( "Open directory {}" , name) ;
360
+
361
+ let mut fs = fs:: FILESYSTEM . lock ( ) ;
362
+ if let Ok ( filesystem_fd) = fs. opendir ( name) {
363
+ let fd = FD_COUNTER . fetch_add ( 1 , Ordering :: SeqCst ) ;
364
+ // Would a GenericDir make sense?
365
+ let file = GenericFile :: new ( filesystem_fd) ;
366
+ if OBJECT_MAP . write ( ) . try_insert ( fd, Arc :: new ( file) ) . is_err ( ) {
367
+ Err ( -EINVAL )
368
+ } else {
369
+ Ok ( fd as FileDescriptor )
370
+ }
371
+ } else {
372
+ Err ( -EINVAL )
373
+ }
374
+ }
375
+ #[ cfg( not( target_arch = "x86_64" ) ) ]
376
+ {
377
+ Err ( -ENOSYS )
378
+ }
379
+ }
380
+ }
381
+
322
382
pub ( crate ) fn get_object ( fd : FileDescriptor ) -> Result < Arc < dyn ObjectInterface > , i32 > {
323
383
Ok ( ( * ( OBJECT_MAP . read ( ) . get ( & fd) . ok_or ( -EINVAL ) ?) ) . clone ( ) )
324
384
}
0 commit comments