ipc_rs/raw.rs
1//! Module containing raw definitions mapping to the underlying IPC protocol
2
3use Message;
4
5use libc::{
6 size_t,
7 IPC_CREAT,
8 IPC_EXCL,
9 IPC_NOWAIT,
10 IPC_RMID,
11 IPC_SET,
12 IPC_STAT,
13 IPC_INFO,
14 MSG_INFO,
15 MSG_STAT,
16 MSG_NOERROR,
17 MSG_EXCEPT,
18 MSG_COPY,
19};
20
21use std::os::raw::{c_int, c_long};
22
23extern "C" {
24 /// Raw `msgsnd()` function; we need to use this declaration as opposed to
25 /// the one in the `libc` crate due to `c_void` type bullshittery.
26 /// Keep in mind that due to the lifetime implications of `*const` pointers
27 /// and lifetimes, you should create the raw pointer during the function
28 /// call (or as late as possible) so that you avoid dangling pointers
29 ///
30 /// Parameters:
31 /// * `msqid` - ID of the message queue in question
32 /// * `msgp` - pointer to a user-defined message struct, such struct is
33 /// required to have two fields: `mtype` and `mtext`, the first being
34 /// a `long`/`i64` which should be positive and the latter an array
35 /// or struct (but not a pointer) as chosen by the user
36 /// * `msgsz` - maximum size of message (only mtext is counted) that can
37 /// be read; depending on configuration, messages larger than `msgsz`
38 /// will be either truncated (MSG_NOERROR flag) or the function will
39 /// fail and set `errno` to `E2BIG` (default behavior)
40 /// * `msgflg` - flags, see [`IpcFlags`] for more info
41 pub fn msgsnd(msqid: c_int, msgp: *const Message, msgsz: size_t, msgflg: c_int) -> c_int;
42
43 /// Raw `msgrcv()` function; see [`msgsnd()`] for more details on usage
44 ///
45 /// Parameters:
46 /// * `msqid` - ID of the message queue in question
47 /// * `msgp` - pointer to a user-defined message struct, such struct is
48 /// required to have two fields: `mtype` and `mtext`, the first being
49 /// a `long`/`i64` which should be positive and the latter an array
50 /// or struct (but not a pointer) as chosen by the user
51 /// * `msgsz` - maximum size of message (only mtext is counted) that can
52 /// be read; depending on configuration, messages larger than `msgsz`
53 /// will be either truncated (MSG_NOERROR flag) or the function will
54 /// fail and set `errno` to `E2BIG` (default behavior)
55 /// * `msgflg` - flags, see [`IpcFlags`] for more info
56 pub fn msgrcv(msqid: c_int, msgp: *mut Message, msgsz: size_t, msgtyp: c_long, msgflg: c_int) -> isize;
57}
58
59
60/// Bit flags for `msgget`
61#[repr(i32)]
62pub enum IpcFlags {
63 /// Create the queue if it doesn't exist
64 CreateKey = IPC_CREAT,
65 /// Fail if not creating and queue doesn't
66 /// exist and fail if creating and queue
67 /// already exists
68 Exclusive = IPC_EXCL,
69 /// Make `send()` and `recv()` async
70 NoWait = IPC_NOWAIT,
71 /// Allow truncation of message data
72 MsgNoError = MSG_NOERROR,
73 /// Used with `msgtyp` greater than 0
74 /// to read the first message in the
75 /// queue with a different type than
76 /// `msgtyp`
77 MsgExcept = MSG_EXCEPT,
78 /// Copy the message instead of removing
79 /// it from the queue. Used for `peek()`
80 MsgCopy = MSG_COPY,
81}
82
83/// Commands for use with `msgctl()`
84#[repr(i32)]
85pub enum ControlCommands {
86 /// Instantly deletes queue,
87 /// sending a signal to all
88 /// waiting processes.
89 ///
90 /// In this case, `msqid_ds` is completely ignored
91 /// and you can theoretically even pass a null pointer
92 /// without having to worry
93 DeleteQueue = IPC_RMID,
94 /// Write the values of some
95 /// members of `msqid_ds` to
96 /// the kernel data structure
97 ///
98 /// Parameters written:
99 /// * `msg_qbytes` - the maximum amount of
100 /// bytes allowed in the queuue. [`msgsnd()`]
101 /// calls over the memory limit will block
102 /// unless [`IpcFlags::NoWait`] is also specified
103 /// * `msg_perm.uid` - UID of the owner of the queue
104 /// (not the same as ID of the creator, which is
105 /// saved in `msg_perm.cuid` and can't be changed)
106 /// * `msg_perm.gid` - group ID of the owner of
107 /// the queue (not the same as GID of the creator,
108 /// which is saved in `msg_perm.cgid` and can't
109 /// be modified)
110 /// * the 9 least significant bits of `msg_perm.mode` -
111 /// these are the same mode bits you would encouter
112 /// when working with files in Unix. Execute bits
113 /// are ignored
114 SetOptions = IPC_SET,
115 /// Copies information from the kernel data structure
116 /// into the `msqid_ds` struct. The caller mus have read
117 /// permission on the message queue in the structure
118 GetOptions = IPC_STAT,
119 /// Returns systen-wide information about message queue
120 /// limits and parameters. In this case, `msgctl()` expects
121 /// a `msginfo` struct as a parameter. Therefore, a cast
122 /// is required
123 ///
124 /// This command is Linux specific.
125 ///
126 /// `msginfo` has the following members with the following
127 /// meanings:
128 /// * `int msgpool` - Size in Kibibites of buffer pool
129 /// used to hold message data; unused within kernel
130 /// * `int msgmap` - maximum number of entries in message
131 /// map, also unused
132 /// * `int msgmax` - maximum numberr of bytes that can be
133 /// written in a single message`
134 /// * `int msgmnb` - maximum number of bytes that can be
135 /// written to a queue; used to initialize msg_qbytes
136 /// * `int msgmni` - maximum number of message queues
137 /// * `int msgssz` - message segment size; unused within
138 /// the Linux kernel
139 /// * `int msgtql` - maximum number of messages on all
140 /// queues in system; unused
141 /// * `unsigned short int msgseg` - maximum number of
142 /// segments; also unusued
143 ///
144 /// The `msgmni`, `msgmax` and `msgmnb` settings can be changed
145 /// through `/proc` files of the same name. These are
146 /// usually located in `/proc/sys/kernel`
147 ///
148 /// For bigger payloads it is recommended to raise `msgmax`
149 ReturnInfo = IPC_INFO,
150 /// Returns a same `msgid_ds` struct as [`ControlCommands::GetOptions`]
151 /// does with the exception that the `msqid` argument is not a queue
152 /// identifier but instead an index into the kernel's internal array
153 ///
154 /// This command is Linux specific and rarely used outside of kernel.
155 MessageStat = MSG_STAT,
156 /// Returns `msginfo` struct just like [`ControlCommands::ReturnInfo`]
157 /// would do, but instead reports information about system resources
158 /// consumed by message queues.
159 ///
160 /// This command is Linux specific.
161 ///
162 /// The changed struct members are:
163 /// * `msgpool` - now returns the number of message queues that currently
164 /// exist on the system
165 /// * `msgmap` - now returns the total number of messages in all queues
166 /// across the system
167 /// * `msgtql` - now returns the total number of bytes used by messages
168 /// accross the system
169 MessageInfo = MSG_INFO,
170}