about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2025-03-23 14:59:33 -0400
committerGitHub <noreply@github.com>2025-03-23 14:59:33 -0400
commitf4096dcda83b1a354121f9d342e04cf87a632ff8 (patch)
treedbb11d997afbb1e4c6a13a1f62793e2ccc6fcdab
parent21cdebcf4ecda073e7b2da47070687d12c1d585e (diff)
parent9fa158d70a75ce116e87b03d913104474af0e381 (diff)
downloadrust-f4096dcda83b1a354121f9d342e04cf87a632ff8.tar.gz
rust-f4096dcda83b1a354121f9d342e04cf87a632ff8.zip
Rollup merge of #138667 - Ayush1325:uefi-mkdir, r=joboet
std: uefi: fs: Implement mkdir

- Since there is no direct mkdir in UEFI, first check if a file/dir with same path exists and then create the directory.

cc `@dvdhrm` `@nicholasbishop`
-rw-r--r--library/std/src/sys/fs/uefi.rs34
1 files changed, 30 insertions, 4 deletions
diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs
index defc1681d38..54acd4c27b3 100644
--- a/library/std/src/sys/fs/uefi.rs
+++ b/library/std/src/sys/fs/uefi.rs
@@ -36,7 +36,7 @@ pub struct FilePermissions(bool);
 pub struct FileType(bool);
 
 #[derive(Debug)]
-pub struct DirBuilder {}
+pub struct DirBuilder;
 
 impl FileAttr {
     pub fn size(&self) -> u64 {
@@ -248,11 +248,11 @@ impl File {
 
 impl DirBuilder {
     pub fn new() -> DirBuilder {
-        DirBuilder {}
+        DirBuilder
     }
 
-    pub fn mkdir(&self, _p: &Path) -> io::Result<()> {
-        unsupported()
+    pub fn mkdir(&self, p: &Path) -> io::Result<()> {
+        uefi_fs::mkdir(p)
     }
 }
 
@@ -452,4 +452,30 @@ mod uefi_fs {
             }
         }
     }
+
+    /// An implementation of mkdir to allow creating new directory without having to open the
+    /// volume twice (once for checking and once for creating)
+    pub(crate) fn mkdir(path: &Path) -> io::Result<()> {
+        let absolute = crate::path::absolute(path)?;
+
+        let p = helpers::OwnedDevicePath::from_text(absolute.as_os_str())?;
+        let (vol, mut path_remaining) = File::open_volume_from_device_path(p.borrow())?;
+
+        // Check if file exists
+        match vol.open(&mut path_remaining, file::MODE_READ, 0) {
+            Ok(_) => {
+                return Err(io::Error::new(io::ErrorKind::AlreadyExists, "Path already exists"));
+            }
+            Err(e) if e.kind() == io::ErrorKind::NotFound => {}
+            Err(e) => return Err(e),
+        }
+
+        let _ = vol.open(
+            &mut path_remaining,
+            file::MODE_READ | file::MODE_WRITE | file::MODE_CREATE,
+            file::DIRECTORY,
+        )?;
+
+        Ok(())
+    }
 }