@@ -11,7 +11,7 @@ use crate::sys::{helpers, unsupported};
1111
1212const FILE_PERMISSIONS_MASK : u64 = r_efi:: protocols:: file:: READ_ONLY ;
1313
14- pub struct File ( ! ) ;
14+ pub struct File ( uefi_fs :: File ) ;
1515
1616#[ derive( Clone ) ]
1717pub struct FileAttr {
@@ -235,9 +235,11 @@ impl OpenOptions {
235235
236236 pub fn create_new ( & mut self , create_new : bool ) {
237237 self . create_new = create_new;
238+ if create_new {
239+ self . create ( true ) ;
240+ }
238241 }
239242
240- #[ expect( dead_code) ]
241243 const fn is_mode_valid ( & self ) -> bool {
242244 // Valid Combinations: Read, Read/Write, Read/Write/Create
243245 self . mode == file:: MODE_READ
@@ -247,100 +249,125 @@ impl OpenOptions {
247249}
248250
249251impl File {
250- pub fn open ( _path : & Path , _opts : & OpenOptions ) -> io:: Result < File > {
251- unsupported ( )
252+ pub fn open ( path : & Path , opts : & OpenOptions ) -> io:: Result < File > {
253+ if !opts. is_mode_valid ( ) {
254+ return Err ( io:: const_error!( io:: ErrorKind :: InvalidInput , "Invalid open options" ) ) ;
255+ }
256+
257+ if opts. create_new && exists ( path) ? {
258+ return Err ( io:: const_error!( io:: ErrorKind :: AlreadyExists , "File already exists" ) ) ;
259+ }
260+
261+ let f = uefi_fs:: File :: from_path ( path, opts. mode , 0 ) . map ( Self ) ?;
262+
263+ if opts. truncate {
264+ f. truncate ( 0 ) ?;
265+ }
266+
267+ if opts. append {
268+ f. seek ( io:: SeekFrom :: End ( 0 ) ) ?;
269+ }
270+
271+ Ok ( f)
252272 }
253273
254274 pub fn file_attr ( & self ) -> io:: Result < FileAttr > {
255- self . 0
275+ self . 0 . file_info ( ) . map ( FileAttr :: from_uefi )
256276 }
257277
258278 pub fn fsync ( & self ) -> io:: Result < ( ) > {
259- self . 0
279+ unsupported ( )
260280 }
261281
262282 pub fn datasync ( & self ) -> io:: Result < ( ) > {
263- self . 0
283+ unsupported ( )
264284 }
265285
266286 pub fn lock ( & self ) -> io:: Result < ( ) > {
267- self . 0
287+ unsupported ( )
268288 }
269289
270290 pub fn lock_shared ( & self ) -> io:: Result < ( ) > {
271- self . 0
291+ unsupported ( )
272292 }
273293
274294 pub fn try_lock ( & self ) -> Result < ( ) , TryLockError > {
275- self . 0
295+ unsupported ( ) . map_err ( TryLockError :: Error )
276296 }
277297
278298 pub fn try_lock_shared ( & self ) -> Result < ( ) , TryLockError > {
279- self . 0
299+ unsupported ( ) . map_err ( TryLockError :: Error )
280300 }
281301
282302 pub fn unlock ( & self ) -> io:: Result < ( ) > {
283- self . 0
303+ unsupported ( )
284304 }
285305
286- pub fn truncate ( & self , _size : u64 ) -> io:: Result < ( ) > {
287- self . 0
306+ pub fn truncate ( & self , size : u64 ) -> io:: Result < ( ) > {
307+ let mut file_info = self . 0 . file_info ( ) ?;
308+
309+ unsafe { ( * file_info. as_mut_ptr ( ) ) . file_size = size } ;
310+
311+ self . 0 . set_file_info ( file_info)
288312 }
289313
290314 pub fn read ( & self , _buf : & mut [ u8 ] ) -> io:: Result < usize > {
291- self . 0
315+ unsupported ( )
292316 }
293317
294- pub fn read_vectored ( & self , _bufs : & mut [ IoSliceMut < ' _ > ] ) -> io:: Result < usize > {
295- self . 0
318+ pub fn read_vectored ( & self , bufs : & mut [ IoSliceMut < ' _ > ] ) -> io:: Result < usize > {
319+ crate :: io :: default_read_vectored ( |b| self . read ( b ) , bufs )
296320 }
297321
298322 pub fn is_read_vectored ( & self ) -> bool {
299- self . 0
323+ false
300324 }
301325
302- pub fn read_buf ( & self , _cursor : BorrowedCursor < ' _ > ) -> io:: Result < ( ) > {
303- self . 0
326+ pub fn read_buf ( & self , cursor : BorrowedCursor < ' _ > ) -> io:: Result < ( ) > {
327+ crate :: io :: default_read_buf ( |buf| self . read ( buf ) , cursor )
304328 }
305329
306330 pub fn write ( & self , _buf : & [ u8 ] ) -> io:: Result < usize > {
307- self . 0
331+ unsupported ( )
308332 }
309333
310- pub fn write_vectored ( & self , _bufs : & [ IoSlice < ' _ > ] ) -> io:: Result < usize > {
311- self . 0
334+ pub fn write_vectored ( & self , bufs : & [ IoSlice < ' _ > ] ) -> io:: Result < usize > {
335+ crate :: io :: default_write_vectored ( |b| self . write ( b ) , bufs )
312336 }
313337
314338 pub fn is_write_vectored ( & self ) -> bool {
315- self . 0
339+ false
316340 }
317341
318342 pub fn flush ( & self ) -> io:: Result < ( ) > {
319- self . 0
343+ unsupported ( )
320344 }
321345
322346 pub fn seek ( & self , _pos : SeekFrom ) -> io:: Result < u64 > {
323- self . 0
347+ unsupported ( )
324348 }
325349
326350 pub fn size ( & self ) -> Option < io:: Result < u64 > > {
327- self . 0
351+ match self . file_attr ( ) {
352+ Ok ( x) => Some ( Ok ( x. size ( ) ) ) ,
353+ Err ( e) => Some ( Err ( e) ) ,
354+ }
328355 }
329356
330357 pub fn tell ( & self ) -> io:: Result < u64 > {
331- self . 0
358+ unsupported ( )
332359 }
333360
334361 pub fn duplicate ( & self ) -> io:: Result < File > {
335- self . 0
362+ unsupported ( )
336363 }
337364
338- pub fn set_permissions ( & self , _perm : FilePermissions ) -> io:: Result < ( ) > {
339- self . 0
365+ pub fn set_permissions ( & self , perm : FilePermissions ) -> io:: Result < ( ) > {
366+ set_perm_inner ( & self . 0 , perm )
340367 }
341368
342- pub fn set_times ( & self , _times : FileTimes ) -> io:: Result < ( ) > {
343- self . 0
369+ pub fn set_times ( & self , times : FileTimes ) -> io:: Result < ( ) > {
370+ set_times_inner ( & self . 0 , times )
344371 }
345372}
346373
@@ -355,8 +382,10 @@ impl DirBuilder {
355382}
356383
357384impl fmt:: Debug for File {
358- fn fmt ( & self , _f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
359- self . 0
385+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
386+ let mut b = f. debug_struct ( "File" ) ;
387+ b. field ( "path" , & self . 0 . path ( ) ) ;
388+ b. finish ( )
360389 }
361390}
362391
@@ -391,14 +420,7 @@ pub fn rename(_old: &Path, _new: &Path) -> io::Result<()> {
391420
392421pub fn set_perm ( p : & Path , perm : FilePermissions ) -> io:: Result < ( ) > {
393422 let f = uefi_fs:: File :: from_path ( p, file:: MODE_READ | file:: MODE_WRITE , 0 ) ?;
394- let mut file_info = f. file_info ( ) ?;
395-
396- unsafe {
397- ( * file_info. as_mut_ptr ( ) ) . attribute =
398- ( ( * file_info. as_ptr ( ) ) . attribute & !FILE_PERMISSIONS_MASK ) | perm. to_attr ( )
399- } ;
400-
401- f. set_file_info ( file_info)
423+ set_perm_inner ( & f, perm)
402424}
403425
404426pub fn set_times ( p : & Path , times : FileTimes ) -> io:: Result < ( ) > {
@@ -408,21 +430,7 @@ pub fn set_times(p: &Path, times: FileTimes) -> io::Result<()> {
408430
409431pub fn set_times_nofollow ( p : & Path , times : FileTimes ) -> io:: Result < ( ) > {
410432 let f = uefi_fs:: File :: from_path ( p, file:: MODE_READ | file:: MODE_WRITE , 0 ) ?;
411- let mut file_info = f. file_info ( ) ?;
412-
413- if let Some ( x) = times. accessed {
414- unsafe {
415- ( * file_info. as_mut_ptr ( ) ) . last_access_time = uefi_fs:: systemtime_to_uefi ( x) ;
416- }
417- }
418-
419- if let Some ( x) = times. modified {
420- unsafe {
421- ( * file_info. as_mut_ptr ( ) ) . modification_time = uefi_fs:: systemtime_to_uefi ( x) ;
422- }
423- }
424-
425- f. set_file_info ( file_info)
433+ set_times_inner ( & f, times)
426434}
427435
428436pub fn rmdir ( p : & Path ) -> io:: Result < ( ) > {
@@ -480,6 +488,35 @@ pub fn copy(_from: &Path, _to: &Path) -> io::Result<u64> {
480488 unsupported ( )
481489}
482490
491+ fn set_perm_inner ( f : & uefi_fs:: File , perm : FilePermissions ) -> io:: Result < ( ) > {
492+ let mut file_info = f. file_info ( ) ?;
493+
494+ unsafe {
495+ ( * file_info. as_mut_ptr ( ) ) . attribute =
496+ ( ( * file_info. as_ptr ( ) ) . attribute & !FILE_PERMISSIONS_MASK ) | perm. to_attr ( )
497+ } ;
498+
499+ f. set_file_info ( file_info)
500+ }
501+
502+ fn set_times_inner ( f : & uefi_fs:: File , times : FileTimes ) -> io:: Result < ( ) > {
503+ let mut file_info = f. file_info ( ) ?;
504+
505+ if let Some ( x) = times. accessed {
506+ unsafe {
507+ ( * file_info. as_mut_ptr ( ) ) . last_access_time = uefi_fs:: systemtime_to_uefi ( x) ;
508+ }
509+ }
510+
511+ if let Some ( x) = times. modified {
512+ unsafe {
513+ ( * file_info. as_mut_ptr ( ) ) . modification_time = uefi_fs:: systemtime_to_uefi ( x) ;
514+ }
515+ }
516+
517+ f. set_file_info ( file_info)
518+ }
519+
483520mod uefi_fs {
484521 use r_efi:: protocols:: { device_path, file, simple_file_system} ;
485522
0 commit comments