Skip to content

Commit

Permalink
Improve unix
Browse files Browse the repository at this point in the history
  • Loading branch information
rbtcollins committed Aug 6, 2022
1 parent 09d4549 commit 40ce8ff
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 23 deletions.
47 changes: 27 additions & 20 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -541,28 +541,35 @@ mod tests {
.collect::<Result<Vec<DirEntry>>>()?
.len()
);
let mut options = OpenOptions::default();
options.create_new(true).write(OpenOptionsWriteMode::Write);
options.open_at(&mut parent_dir, "1")?;
options.open_at(&mut parent_dir, "2")?;
options.mkdir_at(&mut parent_dir, "child")?;
options.open_at(&mut parent_dir, "child\\3")?;
let children = read_dir(&mut parent_dir)?.collect::<Result<Vec<_>>>()?;
let dir_present =
|children: &Vec<DirEntry>, name: &OsStr| children.iter().any(|e| e.name() == name);
assert!(dir_present(&children, OsStr::new("1")), "{:?}", children);
assert!(dir_present(&children, OsStr::new("2")), "{:?}", children);
assert!(
dir_present(&children, OsStr::new("child")),
"{:?}",
children
);
let mut child = OpenOptions::default()
.read(true)
.open_at(&mut parent_dir, "child")?;
let children = read_dir(&mut child)?.collect::<Result<Vec<_>>>()?;
assert_eq!(3, children.len());
assert!(dir_present(&children, OsStr::new("3")), "{:?}", children);
{
let mut options = OpenOptions::default();
options.create_new(true).write(OpenOptionsWriteMode::Write);
options.open_at(&mut parent_dir, "1")?;
options.open_at(&mut parent_dir, "2")?;
options.open_at(&mut options.mkdir_at(&mut parent_dir, "child")?, "3")?;
let children = read_dir(&mut parent_dir)?.collect::<Result<Vec<_>>>()?;
assert!(dir_present(&children, OsStr::new("1")), "{:?}", children);
assert!(dir_present(&children, OsStr::new("2")), "{:?}", children);
assert!(
dir_present(&children, OsStr::new("child")),
"{:?}",
children
);
}
{
let mut child = OpenOptions::default()
.read(true)
.open_at(&mut parent_dir, "child")?;
// Something is permitting the fd for child to be dropped before the
// read_dir fcntl to duplicate the fd. Possibly the FD is writing
// over some other fd which is then separately dropped?
// eprintln!("More Magic");
let children = read_dir(&mut child)?.collect::<Result<Vec<_>>>()?;
assert_eq!(3, children.len(), "{:?}", children);
assert!(dir_present(&children, OsStr::new("3")), "{:?}", children);
}
Ok(())
}
}
6 changes: 3 additions & 3 deletions src/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,8 @@ impl<'a> ReadDirImpl<'a> {
pub fn new(dir_file: &'a mut File) -> Result<Self> {
// clone the FD - Nix takes ownership of the FD, but we're not
// implementing TryInto here.
let new_fd = cvt_r(|| unsafe { libc::fcntl(dir_file.as_raw_fd(), libc::F_DUPFD_CLOEXEC) })?;
let new_fd =
cvt_r(|| unsafe { libc::fcntl(dir_file.as_raw_fd(), libc::F_DUPFD_CLOEXEC, 0) })?;
Ok(ReadDirImpl {
iter: Dir::from_fd(new_fd)?.into_iter(),
_phantom: PhantomData,
Expand All @@ -213,15 +214,14 @@ impl Iterator for ReadDirImpl<'_> {
Some(Err(_e)) => Some(Err(std::io::Error::from_raw_os_error(errno::errno()))),
Some(Ok(e)) => {
let name = OsStr::from_bytes(e.file_name().to_bytes()).to_os_string();
Some(Ok(DirEntryImpl { e, name }))
Some(Ok(DirEntryImpl { name }))
}
}
}
}

#[derive(Debug)]
pub(crate) struct DirEntryImpl {
e: dir::Entry,
name: OsString,
}

Expand Down

0 comments on commit 40ce8ff

Please sign in to comment.