@@ -12,7 +12,7 @@ use crate::sys::time::SystemTime;
1212
1313const FILE_PERMISSIONS_MASK : u64 = r_efi:: protocols:: file:: READ_ONLY ;
1414
15- pub struct File ( ! ) ;
15+ pub struct File ( uefi_fs :: File ) ;
1616
1717#[ derive( Clone ) ]
1818pub struct FileAttr {
@@ -244,9 +244,11 @@ impl OpenOptions {
244244
245245 pub fn create_new ( & mut self , create_new : bool ) {
246246 self . create_new = create_new;
247+ if create_new {
248+ self . create ( true ) ;
249+ }
247250 }
248251
249- #[ expect( dead_code) ]
250252 const fn is_mode_valid ( & self ) -> bool {
251253 // Valid Combinations: Read, Read/Write, Read/Write/Create
252254 self . mode == file:: MODE_READ
@@ -256,100 +258,125 @@ impl OpenOptions {
256258}
257259
258260impl File {
259- pub fn open ( _path : & Path , _opts : & OpenOptions ) -> io:: Result < File > {
260- unsupported ( )
261+ pub fn open ( path : & Path , opts : & OpenOptions ) -> io:: Result < File > {
262+ if !opts. is_mode_valid ( ) {
263+ return Err ( io:: const_error!( io:: ErrorKind :: InvalidInput , "Invalid open options" ) ) ;
264+ }
265+
266+ if opts. create_new && exists ( path) ? {
267+ return Err ( io:: const_error!( io:: ErrorKind :: AlreadyExists , "File already exists" ) ) ;
268+ }
269+
270+ let f = uefi_fs:: File :: from_path ( path, opts. mode , 0 ) . map ( Self ) ?;
271+
272+ if opts. truncate {
273+ f. truncate ( 0 ) ?;
274+ }
275+
276+ if opts. append {
277+ f. seek ( io:: SeekFrom :: End ( 0 ) ) ?;
278+ }
279+
280+ Ok ( f)
261281 }
262282
263283 pub fn file_attr ( & self ) -> io:: Result < FileAttr > {
264- self . 0
284+ self . 0 . file_info ( ) . map ( FileAttr :: from_uefi )
265285 }
266286
267287 pub fn fsync ( & self ) -> io:: Result < ( ) > {
268- self . 0
288+ unsupported ( )
269289 }
270290
271291 pub fn datasync ( & self ) -> io:: Result < ( ) > {
272- self . 0
292+ unsupported ( )
273293 }
274294
275295 pub fn lock ( & self ) -> io:: Result < ( ) > {
276- self . 0
296+ unsupported ( )
277297 }
278298
279299 pub fn lock_shared ( & self ) -> io:: Result < ( ) > {
280- self . 0
300+ unsupported ( )
281301 }
282302
283303 pub fn try_lock ( & self ) -> Result < ( ) , TryLockError > {
284- self . 0
304+ unsupported ( ) . map_err ( TryLockError :: Error )
285305 }
286306
287307 pub fn try_lock_shared ( & self ) -> Result < ( ) , TryLockError > {
288- self . 0
308+ unsupported ( ) . map_err ( TryLockError :: Error )
289309 }
290310
291311 pub fn unlock ( & self ) -> io:: Result < ( ) > {
292- self . 0
312+ unsupported ( )
293313 }
294314
295- pub fn truncate ( & self , _size : u64 ) -> io:: Result < ( ) > {
296- self . 0
315+ pub fn truncate ( & self , size : u64 ) -> io:: Result < ( ) > {
316+ let mut file_info = self . 0 . file_info ( ) ?;
317+
318+ unsafe { ( * file_info. as_mut_ptr ( ) ) . file_size = size } ;
319+
320+ self . 0 . set_file_info ( file_info)
297321 }
298322
299323 pub fn read ( & self , _buf : & mut [ u8 ] ) -> io:: Result < usize > {
300- self . 0
324+ unsupported ( )
301325 }
302326
303- pub fn read_vectored ( & self , _bufs : & mut [ IoSliceMut < ' _ > ] ) -> io:: Result < usize > {
304- self . 0
327+ pub fn read_vectored ( & self , bufs : & mut [ IoSliceMut < ' _ > ] ) -> io:: Result < usize > {
328+ crate :: io :: default_read_vectored ( |b| self . read ( b ) , bufs )
305329 }
306330
307331 pub fn is_read_vectored ( & self ) -> bool {
308- self . 0
332+ false
309333 }
310334
311- pub fn read_buf ( & self , _cursor : BorrowedCursor < ' _ > ) -> io:: Result < ( ) > {
312- self . 0
335+ pub fn read_buf ( & self , cursor : BorrowedCursor < ' _ > ) -> io:: Result < ( ) > {
336+ crate :: io :: default_read_buf ( |buf| self . read ( buf ) , cursor )
313337 }
314338
315339 pub fn write ( & self , _buf : & [ u8 ] ) -> io:: Result < usize > {
316- self . 0
340+ unsupported ( )
317341 }
318342
319- pub fn write_vectored ( & self , _bufs : & [ IoSlice < ' _ > ] ) -> io:: Result < usize > {
320- self . 0
343+ pub fn write_vectored ( & self , bufs : & [ IoSlice < ' _ > ] ) -> io:: Result < usize > {
344+ crate :: io :: default_write_vectored ( |b| self . write ( b ) , bufs )
321345 }
322346
323347 pub fn is_write_vectored ( & self ) -> bool {
324- self . 0
348+ false
325349 }
326350
327351 pub fn flush ( & self ) -> io:: Result < ( ) > {
328- self . 0
352+ unsupported ( )
329353 }
330354
331355 pub fn seek ( & self , _pos : SeekFrom ) -> io:: Result < u64 > {
332- self . 0
356+ unsupported ( )
333357 }
334358
335359 pub fn size ( & self ) -> Option < io:: Result < u64 > > {
336- self . 0
360+ match self . file_attr ( ) {
361+ Ok ( x) => Some ( Ok ( x. size ( ) ) ) ,
362+ Err ( e) => Some ( Err ( e) ) ,
363+ }
337364 }
338365
339366 pub fn tell ( & self ) -> io:: Result < u64 > {
340- self . 0
367+ unsupported ( )
341368 }
342369
343370 pub fn duplicate ( & self ) -> io:: Result < File > {
344- self . 0
371+ unsupported ( )
345372 }
346373
347- pub fn set_permissions ( & self , _perm : FilePermissions ) -> io:: Result < ( ) > {
348- self . 0
374+ pub fn set_permissions ( & self , perm : FilePermissions ) -> io:: Result < ( ) > {
375+ set_perm_inner ( & self . 0 , perm )
349376 }
350377
351- pub fn set_times ( & self , _times : FileTimes ) -> io:: Result < ( ) > {
352- self . 0
378+ pub fn set_times ( & self , times : FileTimes ) -> io:: Result < ( ) > {
379+ set_times_inner ( & self . 0 , times )
353380 }
354381}
355382
@@ -364,8 +391,10 @@ impl DirBuilder {
364391}
365392
366393impl fmt:: Debug for File {
367- fn fmt ( & self , _f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
368- self . 0
394+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
395+ let mut b = f. debug_struct ( "File" ) ;
396+ b. field ( "path" , & self . 0 . path ( ) ) ;
397+ b. finish ( )
369398 }
370399}
371400
@@ -435,14 +464,7 @@ pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
435464
436465pub fn set_perm ( p : & Path , perm : FilePermissions ) -> io:: Result < ( ) > {
437466 let f = uefi_fs:: File :: from_path ( p, file:: MODE_READ | file:: MODE_WRITE , 0 ) ?;
438- let mut file_info = f. file_info ( ) ?;
439-
440- unsafe {
441- ( * file_info. as_mut_ptr ( ) ) . attribute =
442- ( ( * file_info. as_ptr ( ) ) . attribute & !FILE_PERMISSIONS_MASK ) | perm. to_attr ( )
443- } ;
444-
445- f. set_file_info ( file_info)
467+ set_perm_inner ( & f, perm)
446468}
447469
448470pub fn set_times ( p : & Path , times : FileTimes ) -> io:: Result < ( ) > {
@@ -452,21 +474,7 @@ pub fn set_times(p: &Path, times: FileTimes) -> io::Result<()> {
452474
453475pub fn set_times_nofollow ( p : & Path , times : FileTimes ) -> io:: Result < ( ) > {
454476 let f = uefi_fs:: File :: from_path ( p, file:: MODE_READ | file:: MODE_WRITE , 0 ) ?;
455- let mut file_info = f. file_info ( ) ?;
456-
457- if let Some ( x) = times. accessed {
458- unsafe {
459- ( * file_info. as_mut_ptr ( ) ) . last_access_time = uefi_fs:: systemtime_to_uefi ( x) ;
460- }
461- }
462-
463- if let Some ( x) = times. modified {
464- unsafe {
465- ( * file_info. as_mut_ptr ( ) ) . modification_time = uefi_fs:: systemtime_to_uefi ( x) ;
466- }
467- }
468-
469- f. set_file_info ( file_info)
477+ set_times_inner ( & f, times)
470478}
471479
472480pub fn rmdir ( p : & Path ) -> io:: Result < ( ) > {
@@ -524,6 +532,35 @@ pub fn copy(_from: &Path, _to: &Path) -> io::Result<u64> {
524532 unsupported ( )
525533}
526534
535+ fn set_perm_inner ( f : & uefi_fs:: File , perm : FilePermissions ) -> io:: Result < ( ) > {
536+ let mut file_info = f. file_info ( ) ?;
537+
538+ unsafe {
539+ ( * file_info. as_mut_ptr ( ) ) . attribute =
540+ ( ( * file_info. as_ptr ( ) ) . attribute & !FILE_PERMISSIONS_MASK ) | perm. to_attr ( )
541+ } ;
542+
543+ f. set_file_info ( file_info)
544+ }
545+
546+ fn set_times_inner ( f : & uefi_fs:: File , times : FileTimes ) -> io:: Result < ( ) > {
547+ let mut file_info = f. file_info ( ) ?;
548+
549+ if let Some ( x) = times. accessed {
550+ unsafe {
551+ ( * file_info. as_mut_ptr ( ) ) . last_access_time = uefi_fs:: systemtime_to_uefi ( x) ;
552+ }
553+ }
554+
555+ if let Some ( x) = times. modified {
556+ unsafe {
557+ ( * file_info. as_mut_ptr ( ) ) . modification_time = uefi_fs:: systemtime_to_uefi ( x) ;
558+ }
559+ }
560+
561+ f. set_file_info ( file_info)
562+ }
563+
527564mod uefi_fs {
528565 use r_efi:: protocols:: { device_path, file, simple_file_system} ;
529566
0 commit comments