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}