Skip to content

Commit ef70d9e

Browse files
Merge #1966
1966: Added `mq_timedreceive` to `::nix::mqueue`. r=asomers a=DavidCollard Noticed when working on a project that `mq_timedreceive` is missing from the `mqueue` module. Not entirely familiar with best practices around feature gating in tests - I feel like I might have messed up by not including a `#[cfg(feature = "time")]`. Would like a little guidance there. Co-authored-by: David Collard <davidcollardprofessional@gmail.com>
2 parents 73e3c99 + 33643ef commit ef70d9e

File tree

3 files changed

+64
-1
lines changed

3 files changed

+64
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ This project adheres to [Semantic Versioning](https://semver.org/).
1111
(#[1662](https://github.com/nix-rust/nix/pull/1662))
1212
- Added `CanRaw` to `SockProtocol` and `CanBcm` as a separate `SocProtocol` constant.
1313
([#1912](https://github.com/nix-rust/nix/pull/1912))
14+
- Added `mq_timedreceive` to `::nix::mqueue`.
15+
([#1966])(https://github.com/nix-rust/nix/pull/1966)
1416

1517
### Changed
1618

src/mqueue.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,32 @@ pub fn mq_receive(
197197
Errno::result(res).map(|r| r as usize)
198198
}
199199

200+
feature! {
201+
#![feature = "time"]
202+
use crate::sys::time::TimeSpec;
203+
/// Receive a message from a message queue with a timeout
204+
///
205+
/// See also ['mq_timedreceive(2)'](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_receive.html)
206+
pub fn mq_timedreceive(
207+
mqdes: &MqdT,
208+
message: &mut [u8],
209+
msg_prio: &mut u32,
210+
abstime: &TimeSpec,
211+
) -> Result<usize> {
212+
let len = message.len() as size_t;
213+
let res = unsafe {
214+
libc::mq_timedreceive(
215+
mqdes.0,
216+
message.as_mut_ptr() as *mut c_char,
217+
len,
218+
msg_prio as *mut u32,
219+
abstime.as_ref(),
220+
)
221+
};
222+
Errno::result(res).map(|r| r as usize)
223+
}
224+
}
225+
200226
/// Send a message to a message queue
201227
///
202228
/// See also [`mq_send(2)`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html)

test/test_mq.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@ use std::ffi::CString;
33
use std::str;
44

55
use nix::errno::Errno;
6-
use nix::mqueue::{mq_attr_member_t, mq_close, mq_open, mq_receive, mq_send};
6+
use nix::mqueue::{
7+
mq_attr_member_t, mq_close, mq_open, mq_receive, mq_send, mq_timedreceive,
8+
};
79
use nix::mqueue::{MQ_OFlag, MqAttr};
810
use nix::sys::stat::Mode;
11+
use nix::sys::time::{TimeSpec, TimeValLike};
12+
use nix::time::{clock_gettime, ClockId};
913

1014
// Defined as a macro such that the error source is reported as the caller's location.
1115
macro_rules! assert_attr_eq {
@@ -55,6 +59,37 @@ fn test_mq_send_and_receive() {
5559
assert_eq!(msg_to_send, str::from_utf8(&buf[0..len]).unwrap());
5660
}
5761

62+
#[test]
63+
fn test_mq_timedreceive() {
64+
const MSG_SIZE: mq_attr_member_t = 32;
65+
let attr = MqAttr::new(0, 10, MSG_SIZE, 0);
66+
let mq_name = &CString::new(b"/a_nix_test_queue".as_ref()).unwrap();
67+
68+
let oflag0 = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY;
69+
let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH;
70+
let r0 = mq_open(mq_name, oflag0, mode, Some(&attr));
71+
if let Err(Errno::ENOSYS) = r0 {
72+
println!("message queues not supported or module not loaded?");
73+
return;
74+
};
75+
let mqd0 = r0.unwrap();
76+
let msg_to_send = "msg_1";
77+
mq_send(&mqd0, msg_to_send.as_bytes(), 1).unwrap();
78+
79+
let oflag1 = MQ_OFlag::O_CREAT | MQ_OFlag::O_RDONLY;
80+
let mqd1 = mq_open(mq_name, oflag1, mode, Some(&attr)).unwrap();
81+
let mut buf = [0u8; 32];
82+
let mut prio = 0u32;
83+
let abstime =
84+
clock_gettime(ClockId::CLOCK_REALTIME).unwrap() + TimeSpec::seconds(1);
85+
let len = mq_timedreceive(&mqd1, &mut buf, &mut prio, &abstime).unwrap();
86+
assert_eq!(prio, 1);
87+
88+
mq_close(mqd1).unwrap();
89+
mq_close(mqd0).unwrap();
90+
assert_eq!(msg_to_send, str::from_utf8(&buf[0..len]).unwrap());
91+
}
92+
5893
#[test]
5994
fn test_mq_getattr() {
6095
use nix::mqueue::mq_getattr;

0 commit comments

Comments
 (0)