repo: Expose dfd_as_file()

The `dfd()` API returns just an integer.  Add a safe API that
makes a copy of the fd.  What we really want here is `BorrowedFd` from
https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md
but that isn't here yet.
This commit is contained in:
Colin Walters 2021-09-21 08:59:17 -04:00
parent e33767cc2a
commit 955f0ddb9d
2 changed files with 28 additions and 0 deletions

View File

@ -40,6 +40,23 @@ impl Repo {
Repo::new(&gio::File::for_path(path.as_ref()))
}
/// Return a copy of the directory file descriptor for this repository.
#[cfg(any(feature = "v2016_4", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v2016_4")))]
pub fn dfd_as_file(&self) -> std::io::Result<std::fs::File> {
use std::os::unix::prelude::FromRawFd;
use std::os::unix::prelude::IntoRawFd;
unsafe {
// A temporary owned file instance
let dfd = std::fs::File::from_raw_fd(self.dfd());
// So we can call dup() on it
let copy = dfd.try_clone();
// Now release our temporary ownership of the original
let _ = dfd.into_raw_fd();
Ok(copy?)
}
}
/// Find all objects reachable from a commit.
pub fn traverse_commit<P: IsA<gio::Cancellable>>(
&self,

View File

@ -106,6 +106,17 @@ fn should_write_content_to_repo() {
}
}
#[test]
#[cfg(feature = "v2016_4")]
fn repo_file() {
use std::os::unix::fs::MetadataExt;
let test_repo = TestRepo::new();
let m1 = test_repo.repo.dfd_as_file().unwrap().metadata().unwrap();
let m2 = test_repo.repo.dfd_as_file().unwrap().metadata().unwrap();
assert_eq!(m1.dev(), m2.dev());
assert_eq!(m1.ino(), m2.ino());
}
fn copy_file(src: &TestRepo, dest: &TestRepo, obj: &ObjectName) {
let (stream, len) = src
.repo