1 | use nix::dir::{Dir, Type}; |
2 | use nix::fcntl::OFlag; |
3 | use nix::sys::stat::Mode; |
4 | use std::fs::File; |
5 | use tempfile::tempdir; |
6 | |
7 | #[cfg (test)] |
8 | fn 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 |
20 | fn 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] |
42 | fn 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] |
63 | fn ebadf() { |
64 | assert_eq!(Dir::from_fd(-1).unwrap_err(), nix::Error::EBADF); |
65 | } |
66 | |