summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md2
-rw-r--r--src/mqueue.rs26
-rw-r--r--test/test_mq.rs37
3 files changed, 64 insertions, 1 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8ff4176c..9fb4b293 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,8 @@ This project adheres to [Semantic Versioning](https://semver.org/).
(#[1662](https://github.com/nix-rust/nix/pull/1662))
- Added `CanRaw` to `SockProtocol` and `CanBcm` as a separate `SocProtocol` constant.
([#1912](https://github.com/nix-rust/nix/pull/1912))
+- Added `mq_timedreceive` to `::nix::mqueue`.
+ ([#1966])(https://github.com/nix-rust/nix/pull/1966)
### Changed
diff --git a/src/mqueue.rs b/src/mqueue.rs
index 33599bf9..ac183eb5 100644
--- a/src/mqueue.rs
+++ b/src/mqueue.rs
@@ -197,6 +197,32 @@ pub fn mq_receive(
Errno::result(res).map(|r| r as usize)
}
+feature! {
+ #![feature = "time"]
+ use crate::sys::time::TimeSpec;
+ /// Receive a message from a message queue with a timeout
+ ///
+ /// See also ['mq_timedreceive(2)'](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html)
+ pub fn mq_timedreceive(
+ mqdes: &MqdT,
+ message: &mut [u8],
+ msg_prio: &mut u32,
+ abstime: &TimeSpec,
+ ) -> Result<usize> {
+ let len = message.len() as size_t;
+ let res = unsafe {
+ libc::mq_timedreceive(
+ mqdes.0,
+ message.as_mut_ptr() as *mut c_char,
+ len,
+ msg_prio as *mut u32,
+ abstime.as_ref(),
+ )
+ };
+ Errno::result(res).map(|r| r as usize)
+ }
+}
+
/// Send a message to a message queue
///
/// See also [`mq_send(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html)
diff --git a/test/test_mq.rs b/test/test_mq.rs
index 7b48e7ac..f232434e 100644
--- a/test/test_mq.rs
+++ b/test/test_mq.rs
@@ -3,9 +3,13 @@ use std::ffi::CString;
use std::str;
use nix::errno::Errno;
-use nix::mqueue::{mq_attr_member_t, mq_close, mq_open, mq_receive, mq_send};
+use nix::mqueue::{
+ mq_attr_member_t, mq_close, mq_open, mq_receive, mq_send, mq_timedreceive,
+};
use nix::mqueue::{MQ_OFlag, MqAttr};
use nix::sys::stat::Mode;
+use nix::sys::time::{TimeSpec, TimeValLike};
+use nix::time::{clock_gettime, ClockId};
// Defined as a macro such that the error source is reported as the caller's location.
macro_rules! assert_attr_eq {
@@ -56,6 +60,37 @@ fn test_mq_send_and_receive() {
}
#[test]
+fn test_mq_timedreceive() {
+ const MSG_SIZE: mq_attr_member_t = 32;
+ let attr = MqAttr::new(0, 10, MSG_SIZE, 0);
+ let mq_name = &CString::new(b"/a_nix_test_queue".as_ref()).unwrap();
+
+ let oflag0 = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY;
+ let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH;
+ let r0 = mq_open(mq_name, oflag0, mode, Some(&attr));
+ if let Err(Errno::ENOSYS) = r0 {
+ println!("message queues not supported or module not loaded?");
+ return;
+ };
+ let mqd0 = r0.unwrap();
+ let msg_to_send = "msg_1";
+ mq_send(&mqd0, msg_to_send.as_bytes(), 1).unwrap();
+
+ let oflag1 = MQ_OFlag::O_CREAT | MQ_OFlag::O_RDONLY;
+ let mqd1 = mq_open(mq_name, oflag1, mode, Some(&attr)).unwrap();
+ let mut buf = [0u8; 32];
+ let mut prio = 0u32;
+ let abstime =
+ clock_gettime(ClockId::CLOCK_REALTIME).unwrap() + TimeSpec::seconds(1);
+ let len = mq_timedreceive(&mqd1, &mut buf, &mut prio, &abstime).unwrap();
+ assert_eq!(prio, 1);
+
+ mq_close(mqd1).unwrap();
+ mq_close(mqd0).unwrap();
+ assert_eq!(msg_to_send, str::from_utf8(&buf[0..len]).unwrap());
+}
+
+#[test]
fn test_mq_getattr() {
use nix::mqueue::mq_getattr;
const MSG_SIZE: mq_attr_member_t = 32;