Skip to main content

strat9_abi/
flag.rs

1use bitflags::bitflags;
2
3bitflags! {
4    /// Strat9 ABI open flags passed via SYS_OPEN.
5    ///
6    /// These are NOT POSIX O_* values. relibc and other POSIX shims must
7    /// translate from O_* to these bits before invoking the syscall.
8    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
9    pub struct OpenFlags: u32 {
10        const READ      = 1 << 0;
11        const WRITE     = 1 << 1;
12        const CREATE    = 1 << 2;
13        const TRUNCATE  = 1 << 3;
14        const APPEND    = 1 << 4;
15        const DIRECTORY = 1 << 5;
16        const EXCL      = 1 << 6;
17        const NONBLOCK  = 1 << 7;
18        const NOFOLLOW  = 1 << 8;
19        const NOCTTY    = 1 << 9;
20        const SYNC      = 1 << 10;
21
22        const RDONLY = Self::READ.bits();
23        const WRONLY = Self::WRITE.bits();
24        const RDWR   = Self::READ.bits() | Self::WRITE.bits();
25    }
26}
27
28bitflags! {
29    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
30    pub struct MapFlags: u32 {
31        const MAP_SHARED    = 0x01;
32        const MAP_PRIVATE   = 0x02;
33        const MAP_FIXED     = 0x10;
34        const MAP_ANONYMOUS = 0x0020;
35        const MAP_NORESERVE = 0x40;
36        const MAP_POPULATE  = 0x8000;
37        const MAP_LOCKED    = 0x2000;
38        const MAP_GROWSDOWN = 0x0100;
39    }
40}
41
42bitflags! {
43    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
44    pub struct CallFlags: u32 {
45        const READ    = 0x01;
46        const WRITE   = 0x02;
47        const NONBLOCK = 0x04;
48        const PEEK    = 0x08;
49        const WAIT    = 0x10;
50        const NOWAIT  = 0x20;
51    }
52}
53
54bitflags! {
55    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
56    pub struct UnlinkFlags: u32 {
57        const REMOVEDIR = 0o02000000;
58    }
59}
60
61/// Translate POSIX O_* flags to Strat9 ABI `OpenFlags`.
62pub fn posix_oflags_to_strat9(posix: u32) -> OpenFlags {
63    const O_ACCMODE: u32 = 0o3;
64    const O_RDONLY: u32 = 0o000000;
65    const O_WRONLY: u32 = 0o000001;
66    const O_RDWR: u32 = 0o000002;
67    const O_CREAT: u32 = 0o000100;
68    const O_EXCL: u32 = 0o000200;
69    const O_NOCTTY: u32 = 0o000400;
70    const O_TRUNC: u32 = 0o001000;
71    const O_APPEND: u32 = 0o002000;
72    const O_NONBLOCK: u32 = 0o004000;
73    const O_DIRECTORY: u32 = 0o0200000;
74    const O_NOFOLLOW: u32 = 0o0400000;
75    const O_SYNC: u32 = 0o04000000;
76
77    let access = posix & O_ACCMODE;
78    let mut out = OpenFlags::empty();
79
80    match access {
81        O_RDONLY => {
82            out |= OpenFlags::READ;
83        }
84        O_WRONLY => {
85            out |= OpenFlags::WRITE;
86        }
87        O_RDWR => {
88            out |= OpenFlags::READ | OpenFlags::WRITE;
89        }
90        _ => {}
91    }
92
93    if posix & O_CREAT != 0 {
94        out |= OpenFlags::CREATE;
95    }
96    if posix & O_TRUNC != 0 {
97        out |= OpenFlags::TRUNCATE;
98    }
99    if posix & O_APPEND != 0 {
100        out |= OpenFlags::APPEND;
101    }
102    if posix & O_DIRECTORY != 0 {
103        out |= OpenFlags::DIRECTORY;
104    }
105    if posix & O_EXCL != 0 {
106        out |= OpenFlags::EXCL;
107    }
108    if posix & O_NONBLOCK != 0 {
109        out |= OpenFlags::NONBLOCK;
110    }
111    if posix & O_NOFOLLOW != 0 {
112        out |= OpenFlags::NOFOLLOW;
113    }
114    if posix & O_NOCTTY != 0 {
115        out |= OpenFlags::NOCTTY;
116    }
117    if posix & O_SYNC != 0 {
118        out |= OpenFlags::SYNC;
119    }
120
121    out
122}