]> git.proxmox.com Git - rustc.git/blob - src/vendor/nix/src/mqueue.rs
New upstream version 1.23.0+dfsg1
[rustc.git] / src / vendor / nix / src / mqueue.rs
1 //! Posix Message Queue functions
2 //!
3 //! [Further reading and details on the C API](http://man7.org/linux/man-pages/man7/mq_overview.7.html)
4
5 use {Errno, Result};
6
7 use libc::{self, c_char, c_long, mode_t, mqd_t, size_t};
8 use std::ffi::CString;
9 use sys::stat::Mode;
10 use std::mem;
11
12 libc_bitflags!{
13 pub flags MQ_OFlag: libc::c_int {
14 O_RDONLY,
15 O_WRONLY,
16 O_RDWR,
17 O_CREAT,
18 O_EXCL,
19 O_NONBLOCK,
20 O_CLOEXEC,
21 }
22 }
23
24 libc_bitflags!{
25 pub flags FdFlag: libc::c_int {
26 FD_CLOEXEC,
27 }
28 }
29
30 #[repr(C)]
31 #[derive(Clone, Copy)]
32 pub struct MqAttr {
33 mq_attr: libc::mq_attr,
34 }
35
36 impl PartialEq<MqAttr> for MqAttr {
37 fn eq(&self, other: &MqAttr) -> bool {
38 let self_attr = self.mq_attr;
39 let other_attr = other.mq_attr;
40 self_attr.mq_flags == other_attr.mq_flags && self_attr.mq_maxmsg == other_attr.mq_maxmsg &&
41 self_attr.mq_msgsize == other_attr.mq_msgsize &&
42 self_attr.mq_curmsgs == other_attr.mq_curmsgs
43 }
44 }
45
46 impl MqAttr {
47 pub fn new(mq_flags: c_long,
48 mq_maxmsg: c_long,
49 mq_msgsize: c_long,
50 mq_curmsgs: c_long)
51 -> MqAttr {
52 let mut attr = unsafe { mem::uninitialized::<libc::mq_attr>() };
53 attr.mq_flags = mq_flags;
54 attr.mq_maxmsg = mq_maxmsg;
55 attr.mq_msgsize = mq_msgsize;
56 attr.mq_curmsgs = mq_curmsgs;
57 MqAttr { mq_attr: attr }
58 }
59
60 pub fn flags(&self) -> c_long {
61 self.mq_attr.mq_flags
62 }
63 }
64
65
66 pub fn mq_open(name: &CString,
67 oflag: MQ_OFlag,
68 mode: Mode,
69 attr: Option<&MqAttr>)
70 -> Result<mqd_t> {
71 let res = match attr {
72 Some(mq_attr) => unsafe {
73 libc::mq_open(name.as_ptr(),
74 oflag.bits(),
75 mode.bits() as mode_t,
76 &mq_attr.mq_attr as *const libc::mq_attr)
77 },
78 None => unsafe { libc::mq_open(name.as_ptr(), oflag.bits()) },
79 };
80 Errno::result(res)
81 }
82
83 pub fn mq_unlink(name: &CString) -> Result<()> {
84 let res = unsafe { libc::mq_unlink(name.as_ptr()) };
85 Errno::result(res).map(drop)
86 }
87
88 pub fn mq_close(mqdes: mqd_t) -> Result<()> {
89 let res = unsafe { libc::mq_close(mqdes) };
90 Errno::result(res).map(drop)
91 }
92
93 pub fn mq_receive(mqdes: mqd_t, message: &mut [u8], msg_prio: &mut u32) -> Result<usize> {
94 let len = message.len() as size_t;
95 let res = unsafe {
96 libc::mq_receive(mqdes,
97 message.as_mut_ptr() as *mut c_char,
98 len,
99 msg_prio as *mut u32)
100 };
101 Errno::result(res).map(|r| r as usize)
102 }
103
104 pub fn mq_send(mqdes: mqd_t, message: &[u8], msq_prio: u32) -> Result<()> {
105 let res = unsafe {
106 libc::mq_send(mqdes,
107 message.as_ptr() as *const c_char,
108 message.len(),
109 msq_prio)
110 };
111 Errno::result(res).map(drop)
112 }
113
114 pub fn mq_getattr(mqd: mqd_t) -> Result<MqAttr> {
115 let mut attr = unsafe { mem::uninitialized::<libc::mq_attr>() };
116 let res = unsafe { libc::mq_getattr(mqd, &mut attr) };
117 Errno::result(res).map(|_| MqAttr { mq_attr: attr })
118 }
119
120 /// Set the attributes of the message queue. Only `O_NONBLOCK` can be set, everything else will be ignored
121 /// Returns the old attributes
122 /// It is recommend to use the `mq_set_nonblock()` and `mq_remove_nonblock()` convenience functions as they are easier to use
123 ///
124 /// [Further reading](http://man7.org/linux/man-pages/man3/mq_setattr.3.html)
125 pub fn mq_setattr(mqd: mqd_t, newattr: &MqAttr) -> Result<MqAttr> {
126 let mut attr = unsafe { mem::uninitialized::<libc::mq_attr>() };
127 let res = unsafe { libc::mq_setattr(mqd, &newattr.mq_attr as *const libc::mq_attr, &mut attr) };
128 Errno::result(res).map(|_| MqAttr { mq_attr: attr })
129 }
130
131 /// Convenience function.
132 /// Sets the `O_NONBLOCK` attribute for a given message queue descriptor
133 /// Returns the old attributes
134 pub fn mq_set_nonblock(mqd: mqd_t) -> Result<(MqAttr)> {
135 let oldattr = try!(mq_getattr(mqd));
136 let newattr = MqAttr::new(O_NONBLOCK.bits() as c_long,
137 oldattr.mq_attr.mq_maxmsg,
138 oldattr.mq_attr.mq_msgsize,
139 oldattr.mq_attr.mq_curmsgs);
140 mq_setattr(mqd, &newattr)
141 }
142
143 /// Convenience function.
144 /// Removes `O_NONBLOCK` attribute for a given message queue descriptor
145 /// Returns the old attributes
146 pub fn mq_remove_nonblock(mqd: mqd_t) -> Result<(MqAttr)> {
147 let oldattr = try!(mq_getattr(mqd));
148 let newattr = MqAttr::new(0,
149 oldattr.mq_attr.mq_maxmsg,
150 oldattr.mq_attr.mq_msgsize,
151 oldattr.mq_attr.mq_curmsgs);
152 mq_setattr(mqd, &newattr)
153 }