1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
| #![no_std]
#![no_main]
#[macro_use]
#[path = "ulib.rs"]
mod ulib;
use ulib::*;
fn check(failures: &mut i64, ok: bool, what: &str) {
if !ok {
println!("[hello] CHECK FAILED: {}", what);
*failures += 1;
}
}
fn main() -> i64 {
let mut failures = 0;
println!("Hello from user mode! I'm pid {}.", getpid());
let mut buf = [0u8; 128];
let fd = open("/hello.txt", 0);
check(&mut failures, fd >= 3, "open /hello.txt");
let n = read(fd, &mut buf);
let text = core::str::from_utf8(&buf[..n.max(0) as usize]).unwrap_or("<not utf-8>");
print!("[hello] /hello.txt says: {}", text);
check(&mut failures, text.starts_with("Hello from the ramfs!"), "contents of /hello.txt");
check(&mut failures, read(fd, &mut buf) == 0, "read at EOF returns 0");
check(&mut failures, close(fd) == 0, "close");
let fd = open("/tmp/note.txt", O_WRONLY | O_CREAT);
check(&mut failures, write(fd, b"written from ring 3") == 19, "write /tmp/note.txt");
close(fd);
let fd = open("/tmp/note.txt", 0);
let n = read(fd, &mut buf);
check(&mut failures, &buf[..n.max(0) as usize] == b"written from ring 3", "read back /tmp/note.txt");
close(fd);
println!("[hello] wrote and read back /tmp/note.txt");
check(&mut failures, open("/does/not/exist", 0) == -ENOENT, "ENOENT");
check(&mut failures, read(42, &mut buf) == -EBADF, "EBADF");
check(&mut failures, close(fd) == -EBADF, "double close -> EBADF");
let r = syscall3(SYS_WRITE, 1, 0x20_0000, 16);
check(&mut failures, r == -EFAULT, "kernel pointer -> EFAULT");
check(&mut failures, syscall3(999, 0, 0, 0) == -38, "unknown syscall -> ENOSYS");
if failures == 0 {
println!("[hello] all syscall checks passed, exiting with 0");
}
failures
}
|