From 19224a411af0c77f0855fd812b0c16d966129c63 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 3 Feb 2022 08:54:37 -0500 Subject: [PATCH] repo: Add two more cap-std APIs Followup to the previous PR. I realized now with `io_lifetimes` we can offer a safe `dfd_borrow()` that *borrows* the file descriptor for the repository. (In contrast to the current `.dfd()` that returns the raw version) Building on that, add another API that re-acquires a `Dir` instance. (In the future in theory we could optimize this more by knowing whether or not the repo was constructed via cap-std, and perhaps in theory synthesize a `&Dir` reference, but I don't think we need that now) --- rust-bindings/rust/src/repo.rs | 12 ++++++++++++ rust-bindings/rust/tests/repo/mod.rs | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/rust-bindings/rust/src/repo.rs b/rust-bindings/rust/src/repo.rs index ec38ce83..147199c9 100644 --- a/rust-bindings/rust/src/repo.rs +++ b/rust-bindings/rust/src/repo.rs @@ -145,6 +145,18 @@ impl Repo { } } + /// Borrow the directory file descriptor for this repository. + #[cfg(feature = "cap-std-apis")] + pub fn dfd_borrow<'a>(&'a self) -> io_lifetimes::BorrowedFd<'a> { + unsafe { io_lifetimes::BorrowedFd::borrow_raw_fd(self.dfd()) } + } + + /// Return a new `cap-std` directory reference for this repository. + #[cfg(feature = "cap-std-apis")] + pub fn dfd_as_dir(&self) -> std::io::Result { + cap_std::fs::Dir::reopen_dir(&self.dfd_borrow()) + } + /// Find all objects reachable from a commit. pub fn traverse_commit>( &self, diff --git a/rust-bindings/rust/tests/repo/mod.rs b/rust-bindings/rust/tests/repo/mod.rs index 2cfde3db..5d59aa52 100644 --- a/rust-bindings/rust/tests/repo/mod.rs +++ b/rust-bindings/rust/tests/repo/mod.rs @@ -31,6 +31,10 @@ fn should_commit_content_to_repo_and_list_refs_again() { fn cap_std_commit() { let test_repo = CapTestRepo::new(); + assert!(test_repo.dir.exists("config")); + // Also test re-acquiring a new dfd + assert!(test_repo.repo.dfd_as_dir().unwrap().exists("config")); + assert!(test_repo.repo.require_rev("nosuchrev").is_err()); let mtree = create_mtree(&test_repo.repo);