1 //! Posix Message Queue functions
3 //! [Further reading and details on the C API](http://man7.org/linux/man-pages/man7/mq_overview.7.html)
7 use libc
::{self, c_char, c_long, mode_t, mqd_t, size_t}
;
13 pub flags MQ_OFlag
: libc
::c_int
{
25 pub flags FdFlag
: libc
::c_int
{
31 #[derive(Clone, Copy)]
33 mq_attr
: libc
::mq_attr
,
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
47 pub fn new(mq_flags
: c_long
,
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 }
60 pub fn flags(&self) -> c_long
{
66 pub fn mq_open(name
: &CString
,
69 attr
: Option
<&MqAttr
>)
71 let res
= match attr
{
72 Some(mq_attr
) => unsafe {
73 libc
::mq_open(name
.as_ptr(),
75 mode
.bits() as mode_t
,
76 &mq_attr
.mq_attr
as *const libc
::mq_attr
)
78 None
=> unsafe { libc::mq_open(name.as_ptr(), oflag.bits()) }
,
83 pub fn mq_unlink(name
: &CString
) -> Result
<()> {
84 let res
= unsafe { libc::mq_unlink(name.as_ptr()) }
;
85 Errno
::result(res
).map(drop
)
88 pub fn mq_close(mqdes
: mqd_t
) -> Result
<()> {
89 let res
= unsafe { libc::mq_close(mqdes) }
;
90 Errno
::result(res
).map(drop
)
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
;
96 libc
::mq_receive(mqdes
,
97 message
.as_mut_ptr() as *mut c_char
,
101 Errno
::result(res
).map(|r
| r
as usize)
104 pub fn mq_send(mqdes
: mqd_t
, message
: &[u8], msq_prio
: u32) -> Result
<()> {
107 message
.as_ptr() as *const c_char
,
111 Errno
::result(res
).map(drop
)
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 }
)
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
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 }
)
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
)
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
)