1use nix::dir::{Dir, Type}; 2use nix::fcntl::OFlag; 3use nix::sys::stat::Mode; 4use std::fs::File; 5use tempfile::tempdir; 6 7#[cfg(test)] 8fn flags() -> OFlag { 9 #[cfg(target_os = "illumos")] 10 let f = OFlag::O_RDONLY | OFlag::O_CLOEXEC; 11 12 #[cfg(not(target_os = "illumos"))] 13 let f = OFlag::O_RDONLY | OFlag::O_CLOEXEC | OFlag::O_DIRECTORY; 14 15 f 16} 17 18#[test] 19#[allow(clippy::unnecessary_sort_by)] // False positive 20fn read() { 21 let tmp = tempdir().unwrap(); 22 File::create(tmp.path().join("foo")).unwrap(); 23 std::os::unix::fs::symlink("foo", tmp.path().join("bar")).unwrap(); 24 let mut dir = Dir::open(tmp.path(), flags(), Mode::empty()).unwrap(); 25 let mut entries: Vec<_> = dir.iter().map(|e| e.unwrap()).collect(); 26 entries.sort_by(|a, b| a.file_name().cmp(b.file_name())); 27 let entry_names: Vec<_> = entries 28 .iter() 29 .map(|e| e.file_name().to_str().unwrap().to_owned()) 30 .collect(); 31 assert_eq!(&entry_names[..], &[".", "..", "bar", "foo"]); 32 33 // Check file types. The system is allowed to return DT_UNKNOWN (aka None here) but if it does 34 // return a type, ensure it's correct. 35 assert!(&[Some(Type::Directory), None].contains(&entries[0].file_type())); // .: dir 36 assert!(&[Some(Type::Directory), None].contains(&entries[1].file_type())); // ..: dir 37 assert!(&[Some(Type::Symlink), None].contains(&entries[2].file_type())); // bar: symlink 38 assert!(&[Some(Type::File), None].contains(&entries[3].file_type())); // foo: regular file 39} 40 41#[test] 42fn rewind() { 43 let tmp = tempdir().unwrap(); 44 let mut dir = Dir::open(tmp.path(), flags(), Mode::empty()).unwrap(); 45 let entries1: Vec<_> = dir 46 .iter() 47 .map(|e| e.unwrap().file_name().to_owned()) 48 .collect(); 49 let entries2: Vec<_> = dir 50 .iter() 51 .map(|e| e.unwrap().file_name().to_owned()) 52 .collect(); 53 let entries3: Vec<_> = dir 54 .into_iter() 55 .map(|e| e.unwrap().file_name().to_owned()) 56 .collect(); 57 assert_eq!(entries1, entries2); 58 assert_eq!(entries2, entries3); 59} 60 61#[cfg(not(target_os = "haiku"))] 62#[test] 63fn ebadf() { 64 assert_eq!(Dir::from_fd(-1).unwrap_err(), nix::Error::EBADF); 65} 66