Skip to content

Commit 2ac2b18

Browse files
committed
std: sys: fs: uefi: Implement initial File
- Implement basic opening and creating files. - Also implement debug. Signed-off-by: Ayush Singh <ayush@beagleboard.org>
1 parent 7fefa09 commit 2ac2b18

1 file changed

Lines changed: 95 additions & 58 deletions

File tree

library/std/src/sys/fs/uefi.rs

Lines changed: 95 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::sys::{helpers, unsupported};
1111

1212
const 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)]
1717
pub 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

249251
impl 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

357384
impl 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

392421
pub 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

404426
pub fn set_times(p: &Path, times: FileTimes) -> io::Result<()> {
@@ -408,21 +430,7 @@ pub fn set_times(p: &Path, times: FileTimes) -> io::Result<()> {
408430

409431
pub 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

428436
pub 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+
483520
mod uefi_fs {
484521
use r_efi::protocols::{device_path, file, simple_file_system};
485522

0 commit comments

Comments
 (0)