diff options
-rw-r--r-- | src/mqueue.rs | 28 | ||||
-rw-r--r-- | test/test_mq.rs | 21 |
2 files changed, 44 insertions, 5 deletions
diff --git a/src/mqueue.rs b/src/mqueue.rs index 460c7e89..1a2c2ead 100644 --- a/src/mqueue.rs +++ b/src/mqueue.rs @@ -1,3 +1,7 @@ +//! Posis Message Queue functions +//! +//! [Further reading and details on the C API](http://man7.org/linux/man-pages/man7/mq_overview.7.html) + use {Error, Result, from_ffi}; use errno::Errno; @@ -124,7 +128,11 @@ pub fn mq_getattr(mqd: MQd) -> Result<MqAttr> { Ok(attr) } - +/// Set the attributes of the message queue. Only O_NONBLOCK can be set, everything else will be ignored +/// Returns the old attributes +/// It is recommend to use the mq_set_nonblock() and mq_remove_nonblock() convenience functions as they are easier to use +/// +/// [Further reading](http://man7.org/linux/man-pages/man3/mq_setattr.3.html) pub fn mq_setattr(mqd: MQd, newattr: &MqAttr) -> Result<MqAttr> { let mut attr = MqAttr::new(0, 0, 0, 0); let res = unsafe { ffi::mq_setattr(mqd, newattr as *const MqAttr, &mut attr) }; @@ -133,3 +141,21 @@ pub fn mq_setattr(mqd: MQd, newattr: &MqAttr) -> Result<MqAttr> { } Ok(attr) } + +/// Convenience function. +/// Sets the O_NONBLOCK attribute for a given message queue descriptor +/// Returns the old attributes +pub fn mq_set_nonblock(mqd: MQd) -> Result<(MqAttr)> { + let oldattr = try!(mq_getattr(mqd)); + let newattr = MqAttr::new(O_NONBLOCK.bits() as c_long, oldattr.mq_maxmsg, oldattr.mq_msgsize, oldattr.mq_curmsgs); + mq_setattr(mqd, &newattr) +} + +/// Convenience function. +/// Removes O_NONBLOCK attribute for a given message queue descriptor +/// Returns the old attributes +pub fn mq_remove_nonblock(mqd: MQd) -> Result<(MqAttr)> { + let oldattr = try!(mq_getattr(mqd)); + let newattr = MqAttr::new(0, oldattr.mq_maxmsg, oldattr.mq_msgsize, oldattr.mq_curmsgs); + mq_setattr(mqd, &newattr) +} diff --git a/test/test_mq.rs b/test/test_mq.rs index cc661d38..2d7a8955 100644 --- a/test/test_mq.rs +++ b/test/test_mq.rs @@ -1,4 +1,4 @@ -use nix::mqueue::{mq_open, mq_close, mq_send, mq_receive, mq_getattr, mq_setattr, mq_unlink}; +use nix::mqueue::{mq_open, mq_close, mq_send, mq_receive, mq_getattr, mq_setattr, mq_unlink, mq_set_nonblock, mq_remove_nonblock}; use nix::mqueue::{O_CREAT, O_WRONLY, O_RDONLY, O_NONBLOCK}; @@ -55,7 +55,7 @@ fn test_mq_send_and_receive() { #[test] -fn test_mq_get_attr() { +fn test_mq_getattr() { const MSG_SIZE: c_long = 32; let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0); let mq_name = &CString::new("/attr_test_get_attr".as_bytes().as_ref()).unwrap(); @@ -66,7 +66,7 @@ fn test_mq_get_attr() { } #[test] -fn test_mq_set_attr() { +fn test_mq_setattr() { const MSG_SIZE: c_long = 32; let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0); let mq_name = &CString::new("/attr_test_get_attr".as_bytes().as_ref()).unwrap(); @@ -91,7 +91,20 @@ fn test_mq_set_attr() { mq_close(mqd).unwrap(); } - +#[test] +fn test_mq_set_nonblocking() { + const MSG_SIZE: c_long = 32; + let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0); + let mq_name = &CString::new("/attr_test_get_attr".as_bytes().as_ref()).unwrap(); + let mqd = mq_open(mq_name, O_CREAT | O_WRONLY, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH, &initial_attr).unwrap(); + mq_set_nonblock(mqd).unwrap(); + let new_attr = mq_getattr(mqd); + assert!(new_attr.unwrap().mq_flags == O_NONBLOCK.bits() as c_long); + mq_remove_nonblock(mqd).unwrap(); + let new_attr = mq_getattr(mqd); + assert!(new_attr.unwrap().mq_flags == 0); + mq_close(mqd).unwrap(); +} #[test] fn test_mq_unlink() { |