Skip to main content

relibc/header/sys_ipc/
mod.rs

1use crate::{
2    c_str::CStr,
3    error::ResultExt,
4    header::sys_stat::stat,
5    out::Out,
6    platform::{
7        Pal, Sys,
8        types::{c_char, c_int, c_ushort, gid_t, key_t, mode_t, uid_t},
9    },
10};
11
12pub const IPC_R: u32 = 0o400;
13pub const IPC_W: u32 = 0o200;
14pub const IPC_M: u32 = 0o10000;
15
16/// Remove identifier.
17pub const IPC_RMID: i32 = 0;
18/// Set options.
19pub const IPC_SET: i32 = 1;
20/// Get options.
21pub const IPC_STAT: i32 = 2;
22// pub const IPC_INFO: i32 = 3; non posix unimplemented
23
24/// Create entry if key does not exist.
25pub const IPC_CREAT: i32 = 0o1000;
26/// Fail if key exists.
27pub const IPC_EXCL: i32 = 0o2000;
28/// Error if request would need to wait.
29pub const IPC_NOWAIT: i32 = 0o4000;
30
31/// Private key.
32pub const IPC_PRIVATE: key_t = 0;
33
34#[repr(C)]
35#[derive(Copy, Clone, Debug)]
36pub struct ipc_perm {
37    pub __key: key_t,
38    pub uid: uid_t,
39    pub gid: gid_t,
40    pub cuid: uid_t,
41    pub cgid: gid_t,
42    pub mode: mode_t,
43    pub __seq: c_ushort,
44}
45
46/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/ftok.html>.
47#[unsafe(no_mangle)]
48pub unsafe extern "C" fn ftok(path: *const c_char, id: c_int) -> key_t {
49    let path = unsafe { CStr::from_ptr(path) };
50    let mut stat = stat::default();
51    if Sys::stat(path, Out::from_mut(&mut stat))
52        .map(|()| 0)
53        .or_minus_one_errno()
54        == -1
55    {
56        return -1;
57    }
58
59    // Borrowed from musl
60    (stat.st_ino & 0xffff) as key_t | ((stat.st_dev & 0xff) << 16) as key_t | ((id & 0xff) << 24)
61}