• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #[macro_use]
2 extern crate cfg_if;
3 #[cfg_attr(not(any(target_os = "redox", target_os = "haiku")), macro_use)]
4 extern crate nix;
5 #[macro_use]
6 extern crate lazy_static;
7 
8 mod common;
9 mod sys;
10 #[cfg(not(target_os = "redox"))]
11 mod test_dir;
12 mod test_fcntl;
13 #[cfg(any(target_os = "android", target_os = "linux"))]
14 mod test_kmod;
15 #[cfg(any(
16     target_os = "dragonfly",
17     target_os = "freebsd",
18     target_os = "fushsia",
19     target_os = "linux",
20     target_os = "netbsd"
21 ))]
22 mod test_mq;
23 #[cfg(not(target_os = "redox"))]
24 mod test_net;
25 mod test_nix_path;
26 #[cfg(target_os = "freebsd")]
27 mod test_nmount;
28 mod test_poll;
29 #[cfg(not(any(
30     target_os = "redox",
31     target_os = "fuchsia",
32     target_os = "haiku"
33 )))]
34 mod test_pty;
35 mod test_resource;
36 #[cfg(any(
37     target_os = "android",
38     target_os = "dragonfly",
39     all(target_os = "freebsd", fbsd14),
40     target_os = "linux"
41 ))]
42 mod test_sched;
43 #[cfg(any(
44     target_os = "android",
45     target_os = "dragonfly",
46     target_os = "freebsd",
47     target_os = "ios",
48     target_os = "linux",
49     target_os = "macos"
50 ))]
51 mod test_sendfile;
52 mod test_stat;
53 mod test_time;
54 #[cfg(all(
55     any(
56         target_os = "freebsd",
57         target_os = "illumos",
58         target_os = "linux",
59         target_os = "netbsd"
60     ),
61     feature = "time",
62     feature = "signal"
63 ))]
64 mod test_timer;
65 mod test_unistd;
66 
67 use nix::unistd::{chdir, getcwd, read};
68 use parking_lot::{Mutex, RwLock, RwLockWriteGuard};
69 use std::os::unix::io::RawFd;
70 use std::path::PathBuf;
71 
72 /// Helper function analogous to `std::io::Read::read_exact`, but for `RawFD`s
read_exact(f: RawFd, buf: &mut [u8])73 fn read_exact(f: RawFd, buf: &mut [u8]) {
74     let mut len = 0;
75     while len < buf.len() {
76         // get_mut would be better than split_at_mut, but it requires nightly
77         let (_, remaining) = buf.split_at_mut(len);
78         len += read(f, remaining).unwrap();
79     }
80 }
81 
82 lazy_static! {
83     /// Any test that changes the process's current working directory must grab
84     /// the RwLock exclusively.  Any process that cares about the current
85     /// working directory must grab it shared.
86     pub static ref CWD_LOCK: RwLock<()> = RwLock::new(());
87     /// Any test that creates child processes must grab this mutex, regardless
88     /// of what it does with those children.
89     pub static ref FORK_MTX: Mutex<()> = Mutex::new(());
90     /// Any test that changes the process's supplementary groups must grab this
91     /// mutex
92     pub static ref GROUPS_MTX: Mutex<()> = Mutex::new(());
93     /// Any tests that loads or unloads kernel modules must grab this mutex
94     pub static ref KMOD_MTX: Mutex<()> = Mutex::new(());
95     /// Any test that calls ptsname(3) must grab this mutex.
96     pub static ref PTSNAME_MTX: Mutex<()> = Mutex::new(());
97     /// Any test that alters signal handling must grab this mutex.
98     pub static ref SIGNAL_MTX: Mutex<()> = Mutex::new(());
99 }
100 
101 /// RAII object that restores a test's original directory on drop
102 struct DirRestore<'a> {
103     d: PathBuf,
104     _g: RwLockWriteGuard<'a, ()>,
105 }
106 
107 impl<'a> DirRestore<'a> {
new() -> Self108     fn new() -> Self {
109         let guard = crate::CWD_LOCK.write();
110         DirRestore {
111             _g: guard,
112             d: getcwd().unwrap(),
113         }
114     }
115 }
116 
117 impl<'a> Drop for DirRestore<'a> {
drop(&mut self)118     fn drop(&mut self) {
119         let r = chdir(&self.d);
120         if std::thread::panicking() {
121             r.unwrap();
122         }
123     }
124 }
125