1 #[test]
chdir()2 fn chdir() {
3     use std::str;
4 
5     let mut current_buf = [0; 4096];
6     let current_count = dbg!(crate::getcwd(&mut current_buf)).unwrap();
7     let current = dbg!(str::from_utf8(&current_buf[..current_count])).unwrap();
8 
9     let new = "file:";
10     assert_eq!(dbg!(crate::chdir(dbg!(new))), Ok(0));
11     {
12         let mut buf = [0; 4096];
13         let count = dbg!(crate::getcwd(&mut buf)).unwrap();
14         assert_eq!(dbg!(str::from_utf8(&buf[..count])), Ok(new));
15     }
16 
17     assert_eq!(dbg!(crate::chdir(current)), Ok(0));
18     {
19         let mut buf = [0; 4096];
20         let count = dbg!(crate::getcwd(&mut buf)).unwrap();
21         assert_eq!(dbg!(str::from_utf8(&buf[..count])), Ok(current));
22     }
23 }
24 
25 //TODO: chmod
26 
27 #[test]
clone()28 fn clone() {
29     let expected_status = 42;
30     let pid_res = unsafe { crate::clone(crate::CloneFlags::empty()) };
31     if pid_res == Ok(0) {
32         crate::exit(expected_status).unwrap();
33         panic!("failed to exit");
34     } else {
35         let pid = dbg!(pid_res).unwrap();
36         let mut status = 0;
37         assert_eq!(dbg!(crate::waitpid(pid, &mut status, crate::WaitFlags::empty())), Ok(pid));
38         assert_eq!(dbg!(crate::wifexited(status)), true);
39         assert_eq!(dbg!(crate::wexitstatus(status)), expected_status);
40     }
41 }
42 
43 //TODO: close
44 
45 #[test]
clock_gettime()46 fn clock_gettime() {
47     let mut tp = crate::TimeSpec::default();
48     assert_eq!(dbg!(
49         crate::clock_gettime(crate::CLOCK_MONOTONIC, &mut tp)
50     ), Ok(0));
51     assert_ne!(dbg!(tp), crate::TimeSpec::default());
52 
53     tp = crate::TimeSpec::default();
54     assert_eq!(dbg!(
55         crate::clock_gettime(crate::CLOCK_REALTIME, &mut tp)
56     ), Ok(0));
57     assert_ne!(dbg!(tp), crate::TimeSpec::default());
58 }
59 
60 //TODO: dup
61 
62 //TODO: dup2
63 
64 //TODO: exit (handled by clone?)
65 
66 //TODO: fchmod
67 
68 //TODO: fcntl
69 
70 #[test]
fexec()71 fn fexec() {
72     let name = "file:/bin/ls";
73 
74     let fd = dbg!(
75         crate::open(name, crate::O_RDONLY | crate::O_CLOEXEC)
76     ).unwrap();
77 
78     let args = &[
79         [name.as_ptr() as usize, name.len()]
80     ];
81 
82     let vars = &[];
83 
84     let pid_res = unsafe { crate::clone(crate::CloneFlags::empty()) };
85     if pid_res == Ok(0) {
86         crate::fexec(fd, args, vars).unwrap();
87         panic!("failed to fexec");
88     } else {
89         assert_eq!(dbg!(crate::close(fd)), Ok(0));
90 
91         let pid = dbg!(pid_res).unwrap();
92         let mut status = 0;
93         assert_eq!(dbg!(crate::waitpid(pid, &mut status, crate::WaitFlags::empty())), Ok(pid));
94         assert_eq!(dbg!(crate::wifexited(status)), true);
95         assert_eq!(dbg!(crate::wexitstatus(status)), 0);
96     }
97 }
98 
99 #[test]
fmap()100 fn fmap() {
101     use std::slice;
102 
103     let fd = dbg!(
104         crate::open(
105             "file:/tmp/syscall-tests-fmap",
106             crate::O_CREAT | crate::O_RDWR | crate::O_CLOEXEC
107         )
108     ).unwrap();
109 
110     let size = 128;
111 
112     let map = unsafe {
113         slice::from_raw_parts_mut(
114             dbg!(
115                 crate::fmap(fd, &crate::Map {
116                     address: 0,
117                     offset: 0,
118                     size,
119                     flags: crate::PROT_READ | crate::PROT_WRITE
120                 })
121             ).unwrap() as *mut u8,
122             128
123         )
124     };
125 
126     // Maps should be available after closing
127     assert_eq!(dbg!(crate::close(fd)), Ok(0));
128 
129     for i in 0..128 {
130         map[i as usize] = i;
131         assert_eq!(map[i as usize], i);
132     }
133 
134     //TODO: add msync
135     unsafe {
136         assert_eq!(dbg!(
137             crate::funmap(map.as_mut_ptr() as usize, size)
138         ), Ok(0));
139     }
140 }
141 
142 // funmap tested by fmap
143 
144 #[test]
fpath()145 fn fpath() {
146     use std::str;
147 
148     let path = "file:/tmp/syscall-tests-fpath";
149     let fd = dbg!(
150         crate::open(
151             dbg!(path),
152             crate::O_CREAT | crate::O_RDWR | crate::O_CLOEXEC
153         )
154     ).unwrap();
155 
156     let mut buf = [0; 4096];
157     let count = dbg!(
158         crate::fpath(fd, &mut buf)
159     ).unwrap();
160 
161     assert_eq!(dbg!(str::from_utf8(&buf[..count])), Ok(path));
162 
163     assert_eq!(dbg!(crate::close(fd)), Ok(0));
164 }
165 
166 //TODO: frename
167 
168 #[test]
fstat()169 fn fstat() {
170     let path = "file:/tmp/syscall-tests-fstat";
171     let fd = dbg!(
172         crate::open(
173             dbg!(path),
174             crate::O_CREAT | crate::O_RDWR | crate::O_CLOEXEC
175         )
176     ).unwrap();
177 
178     let mut stat = crate::Stat::default();
179     assert_eq!(dbg!(crate::fstat(fd, &mut stat)), Ok(0));
180     assert_ne!(dbg!(stat), crate::Stat::default());
181 
182     assert_eq!(dbg!(crate::close(fd)), Ok(0));
183 }
184 
185 #[test]
fstatvfs()186 fn fstatvfs() {
187     let path = "file:/tmp/syscall-tests-fstatvfs";
188     let fd = dbg!(
189         crate::open(
190             dbg!(path),
191             crate::O_CREAT | crate::O_RDWR | crate::O_CLOEXEC
192         )
193     ).unwrap();
194 
195     let mut statvfs = crate::StatVfs::default();
196     assert_eq!(dbg!(crate::fstatvfs(fd, &mut statvfs)), Ok(0));
197     assert_ne!(dbg!(statvfs), crate::StatVfs::default());
198 
199     assert_eq!(dbg!(crate::close(fd)), Ok(0));
200 }
201 
202 //TODO: fsync
203 
204 //TODO: ftruncate
205 
206 //TODO: futimens
207 
208 //TODO: futex
209 
210 // getcwd tested by chdir
211 
212 #[test]
getegid()213 fn getegid() {
214     assert_eq!(crate::getegid(), Ok(0));
215 }
216 
217 #[test]
getens()218 fn getens() {
219     assert_eq!(crate::getens(), Ok(1));
220 }
221 
222 #[test]
geteuid()223 fn geteuid() {
224     assert_eq!(crate::geteuid(), Ok(0));
225 }
226 
227 #[test]
getgid()228 fn getgid() {
229     assert_eq!(crate::getgid(), Ok(0));
230 }
231 
232 #[test]
getns()233 fn getns() {
234     assert_eq!(crate::getns(), Ok(1));
235 }
236 
237 //TODO: getpid
238 
239 //TODO: getpgid
240 
241 //TODO: getppid
242 
243 #[test]
getuid()244 fn getuid() {
245     assert_eq!(crate::getuid(), Ok(0));
246 }
247 
248 //TODO: iopl
249 
250 //TODO: kill
251 
252 //TODO: link (probably will not work)
253 
254 #[test]
lseek()255 fn lseek() {
256     let path = "file:/tmp/syscall-tests-lseek";
257     let fd = dbg!(
258         crate::open(
259             dbg!(path),
260             crate::O_CREAT | crate::O_RDWR | crate::O_CLOEXEC
261         )
262     ).unwrap();
263 
264     {
265         let mut buf = [0; 256];
266         for i in 0..buf.len() {
267             buf[i] = i as u8;
268         }
269         assert_eq!(dbg!(crate::write(fd, &buf)), Ok(buf.len()));
270 
271         assert_eq!(dbg!(crate::lseek(fd, 0, crate::SEEK_CUR)), Ok(buf.len()));
272         assert_eq!(dbg!(crate::lseek(fd, 0, crate::SEEK_SET)), Ok(0));
273         assert_eq!(dbg!(crate::lseek(fd, 0, crate::SEEK_END)), Ok(buf.len()));
274         assert_eq!(dbg!(crate::lseek(fd, 0, crate::SEEK_SET)), Ok(0));
275     }
276 
277     {
278         let mut buf = [0; 256];
279         assert_eq!(dbg!(crate::read(fd, &mut buf)), Ok(buf.len()));
280         for i in 0..buf.len() {
281             assert_eq!(buf[i], i as u8);
282         }
283 
284         assert_eq!(dbg!(crate::lseek(fd, 0, crate::SEEK_CUR)), Ok(buf.len()));
285         assert_eq!(dbg!(crate::lseek(fd, 0, crate::SEEK_SET)), Ok(0));
286         assert_eq!(dbg!(crate::lseek(fd, 0, crate::SEEK_END)), Ok(buf.len()));
287         assert_eq!(dbg!(crate::lseek(fd, 0, crate::SEEK_SET)), Ok(0));
288     }
289 
290     assert_eq!(dbg!(crate::close(fd)), Ok(0));
291 }
292 
293 //TODO: mkns
294 
295 //TODO: mprotect
296 
297 #[test]
nanosleep()298 fn nanosleep() {
299     let req = crate::TimeSpec {
300         tv_sec: 0,
301         tv_nsec: 0,
302     };
303     let mut rem = crate::TimeSpec::default();
304     assert_eq!(crate::nanosleep(&req, &mut rem), Ok(0));
305     assert_eq!(rem, crate::TimeSpec::default());
306 }
307 
308 //TODO: open
309 
310 //TODO: physalloc
311 
312 //TODO: physfree
313 
314 //TODO: physmap
315 
316 //TODO: physunmap
317 
318 #[test]
pipe2()319 fn pipe2() {
320     let mut fds = [0, 0];
321     assert_eq!(dbg!(crate::pipe2(&mut fds, crate::O_CLOEXEC)), Ok(0));
322     assert_ne!(dbg!(fds), [0, 0]);
323 
324     {
325         let mut buf = [0; 256];
326         for i in 0..buf.len() {
327             buf[i] = i as u8;
328         }
329         assert_eq!(dbg!(crate::write(fds[1], &buf)), Ok(buf.len()));
330     }
331 
332     {
333         let mut buf = [0; 256];
334         assert_eq!(dbg!(crate::read(fds[0], &mut buf)), Ok(buf.len()));
335         for i in 0..buf.len() {
336             assert_eq!(buf[i], i as u8);
337         }
338     }
339 
340     assert_eq!(dbg!(crate::close(fds[0])), Ok(0));
341     assert_eq!(dbg!(crate::close(fds[1])), Ok(0));
342 }
343 
344 //TODO: read
345 
346 #[test]
rmdir()347 fn rmdir() {
348     let path = "file:/tmp/syscall-tests-rmdir";
349     let fd = dbg!(
350         crate::open(
351             dbg!(path),
352             crate::O_CREAT | crate::O_DIRECTORY | crate::O_CLOEXEC
353         )
354     ).unwrap();
355 
356     assert_eq!(dbg!(crate::close(fd)), Ok(0));
357 
358     assert_eq!(dbg!(crate::rmdir(path)), Ok(0));
359 }
360 
361 //TODO: setpgid
362 
363 //TODO: setregid
364 
365 //TODO: setrens
366 
367 //TODO: setreuid
368 
369 //TODO: sigaction
370 
371 //TODO: sigprocmask
372 
373 //TODO: sigreturn
374 
375 #[test]
umask()376 fn umask() {
377     let old = dbg!(crate::umask(0o244)).unwrap();
378     assert_eq!(dbg!(crate::umask(old)), Ok(0o244));
379 }
380 
381 #[test]
unlink()382 fn unlink() {
383     let path = "file:/tmp/syscall-tests-unlink";
384     let fd = dbg!(
385         crate::open(
386             dbg!(path),
387             crate::O_CREAT | crate::O_RDWR | crate::O_CLOEXEC
388         )
389     ).unwrap();
390 
391     assert_eq!(dbg!(crate::close(fd)), Ok(0));
392 
393     assert_eq!(dbg!(crate::unlink(path)), Ok(0));
394 }
395 
396 //TODO: virttophys
397 
398 // waitpid tested by clone
399 
400 //TODO: write
401 
402 #[test]
sched_yield()403 fn sched_yield() {
404     assert_eq!(dbg!(crate::sched_yield()), Ok(0));
405 }
406 
407 #[test]
sigaction()408 fn sigaction() {
409     use std::{
410         mem,
411         sync::atomic::{AtomicBool, Ordering}
412     };
413 
414     static SA_HANDLER_WAS_RAN: AtomicBool = AtomicBool::new(false);
415     static SA_HANDLER_2_WAS_IGNORED: AtomicBool = AtomicBool::new(false);
416 
417     let child = unsafe { crate::clone(crate::CLONE_VM).unwrap() };
418 
419     if child == 0 {
420         let pid = crate::getpid().unwrap();
421 
422         extern "C" fn hello_im_a_signal_handler(signal: usize) {
423             assert_eq!(signal, crate::SIGUSR1);
424             SA_HANDLER_WAS_RAN.store(true, Ordering::SeqCst);
425         }
426 
427         let my_signal_handler = crate::SigAction {
428             sa_handler: Some(hello_im_a_signal_handler),
429             ..Default::default()
430         };
431         crate::sigaction(crate::SIGUSR1, Some(&my_signal_handler), None).unwrap();
432 
433         crate::kill(pid, crate::SIGUSR1).unwrap(); // calls handler
434 
435         let mut old_signal_handler = crate::SigAction::default();
436         crate::sigaction(
437             crate::SIGUSR1,
438             Some(&crate::SigAction {
439                 sa_handler: unsafe { mem::transmute::<usize, Option<extern "C" fn(usize)>>(crate::SIG_IGN) },
440                 ..Default::default()
441             }),
442             Some(&mut old_signal_handler)
443         ).unwrap();
444         assert_eq!(my_signal_handler, old_signal_handler);
445 
446         crate::kill(pid, crate::SIGUSR1).unwrap(); // does nothing
447 
448         SA_HANDLER_2_WAS_IGNORED.store(true, Ordering::SeqCst);
449 
450         crate::sigaction(
451             crate::SIGUSR1,
452             Some(&crate::SigAction {
453                 sa_handler: unsafe { mem::transmute::<usize, Option<extern "C" fn(usize)>>(crate::SIG_DFL) },
454                 ..Default::default()
455             }),
456             Some(&mut old_signal_handler)
457         ).unwrap();
458 
459         crate::kill(pid, crate::SIGUSR1).unwrap(); // actually exits
460     } else {
461         let mut status = 0;
462         dbg!(crate::waitpid(child, &mut status, crate::WaitFlags::empty())).unwrap();
463 
464         assert!(crate::wifsignaled(status));
465         assert_eq!(crate::wtermsig(status), crate::SIGUSR1);
466 
467         assert!(SA_HANDLER_WAS_RAN.load(Ordering::SeqCst));
468         assert!(SA_HANDLER_2_WAS_IGNORED.load(Ordering::SeqCst));
469     }
470 }
471