Skip to content

Commit 47e06d7

Browse files
committed
std: sys: fs: uefi: Implement set_times and set_perm
- Tested on QEMU OVMF. Signed-off-by: Ayush Singh <ayush@beagleboard.org>
1 parent a4cfac7 commit 47e06d7

File tree

2 files changed

+46
-10
lines changed

2 files changed

+46
-10
lines changed

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

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use crate::path::{Path, PathBuf};
99
use crate::sys::time::SystemTime;
1010
use crate::sys::{helpers, unsupported};
1111

12-
#[expect(dead_code)]
1312
const FILE_PERMISSIONS_MASK: u64 = r_efi::protocols::file::READ_ONLY;
1413

1514
pub struct File(!);
@@ -109,7 +108,6 @@ impl FilePermissions {
109108
Self(attr & r_efi::protocols::file::READ_ONLY != 0)
110109
}
111110

112-
#[expect(dead_code)]
113111
const fn to_attr(&self) -> u64 {
114112
if self.0 { r_efi::protocols::file::READ_ONLY } else { 0 }
115113
}
@@ -366,16 +364,40 @@ pub fn rename(_old: &Path, _new: &Path) -> io::Result<()> {
366364
unsupported()
367365
}
368366

369-
pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> {
370-
unsupported()
367+
pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> {
368+
let f = uefi_fs::File::from_path(p, file::MODE_READ | file::MODE_WRITE, 0)?;
369+
let mut file_info = f.file_info()?;
370+
371+
unsafe {
372+
(*file_info.as_mut_ptr()).attribute =
373+
((*file_info.as_ptr()).attribute & !FILE_PERMISSIONS_MASK) | perm.to_attr()
374+
};
375+
376+
f.set_file_info(file_info)
371377
}
372378

373-
pub fn set_times(_p: &Path, _times: FileTimes) -> io::Result<()> {
374-
unsupported()
379+
pub fn set_times(p: &Path, times: FileTimes) -> io::Result<()> {
380+
// UEFI does not support symlinks
381+
set_times_nofollow(p, times)
375382
}
376383

377-
pub fn set_times_nofollow(_p: &Path, _times: FileTimes) -> io::Result<()> {
378-
unsupported()
384+
pub fn set_times_nofollow(p: &Path, times: FileTimes) -> io::Result<()> {
385+
let f = uefi_fs::File::from_path(p, file::MODE_READ | file::MODE_WRITE, 0)?;
386+
let mut file_info = f.file_info()?;
387+
388+
if let Some(x) = times.accessed {
389+
unsafe {
390+
(*file_info.as_mut_ptr()).last_access_time = uefi_fs::systemtime_to_uefi(x);
391+
}
392+
}
393+
394+
if let Some(x) = times.modified {
395+
unsafe {
396+
(*file_info.as_mut_ptr()).modification_time = uefi_fs::systemtime_to_uefi(x);
397+
}
398+
}
399+
400+
f.set_file_info(file_info)
379401
}
380402

381403
pub fn rmdir(p: &Path) -> io::Result<()> {
@@ -560,6 +582,17 @@ mod uefi_fs {
560582
if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(info) }
561583
}
562584

585+
pub(crate) fn set_file_info(&self, mut info: UefiBox<file::Info>) -> io::Result<()> {
586+
let file_ptr = self.0.as_ptr();
587+
let mut info_id = file::INFO_ID;
588+
589+
let r = unsafe {
590+
((*file_ptr).set_info)(file_ptr, &mut info_id, info.len(), info.as_mut_ptr().cast())
591+
};
592+
593+
if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) }
594+
}
595+
563596
pub(crate) fn delete(self) -> io::Result<()> {
564597
let file_ptr = self.0.as_ptr();
565598
let r = unsafe { ((*file_ptr).delete)(file_ptr) };
@@ -643,8 +676,7 @@ mod uefi_fs {
643676
}
644677

645678
/// Convert to UEFI Time with the current timezone.
646-
#[expect(dead_code)]
647-
fn systemtime_to_uefi(time: SystemTime) -> r_efi::efi::Time {
679+
pub(crate) fn systemtime_to_uefi(time: SystemTime) -> r_efi::efi::Time {
648680
let now = time::system_time_internal::now();
649681
time.to_uefi_loose(now.timezone, now.daylight)
650682
}

library/std/src/sys/pal/uefi/helpers.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,10 @@ impl<T> UefiBox<T> {
802802
pub(crate) fn as_ptr(&self) -> *const T {
803803
self.inner.as_ptr().cast()
804804
}
805+
806+
pub(crate) const fn len(&self) -> usize {
807+
self.size
808+
}
805809
}
806810

807811
impl<T> Drop for UefiBox<T> {

0 commit comments

Comments
 (0)