Skip to content

Commit dcd4198

Browse files
committed
Add a timed send to match the timed receive
1 parent a72936d commit dcd4198

File tree

3 files changed

+90
-0
lines changed

3 files changed

+90
-0
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@ This project adheres to [Semantic Versioning](https://semver.org/).
33

44
# Change Log
55

6+
## [Unreleased] - ReleaseDate
7+
8+
### Added
9+
10+
- Added `mq_timedsend` to `::nix::mqueue`.
11+
([#2650](https://github.com/nix-rust/nix/pull/2650))
12+
613
## [0.30.1] - 2025-05-04
714

815
### Fixed

src/mqueue.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,26 @@ feature! {
235235
};
236236
Errno::result(res).map(|r| r as usize)
237237
}
238+
/// Send a message to a message queue with a timeout
239+
///
240+
/// See also ['mq_timedsend(2)'](https://pubs.opengroup.org/onlinepubs/9699919799/functions/mq_send.html)
241+
pub fn mq_timedsend(
242+
mqdes: &MqdT,
243+
message: &[u8],
244+
msg_prio: u32,
245+
abstime: &TimeSpec,
246+
) -> Result<()> {
247+
let res = unsafe {
248+
libc::mq_timedsend(
249+
mqdes.0,
250+
message.as_ptr().cast(),
251+
message.len(),
252+
msg_prio,
253+
abstime.as_ref(),
254+
)
255+
};
256+
Errno::result(res).map(drop)
257+
}
238258
}
239259

240260
/// Send a message to a message queue

test/test_mq.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::str;
44
use nix::errno::Errno;
55
use nix::mqueue::{
66
mq_attr_member_t, mq_close, mq_open, mq_receive, mq_send, mq_timedreceive,
7+
mq_timedsend, mq_unlink,
78
};
89
use nix::mqueue::{MQ_OFlag, MqAttr};
910
use nix::sys::stat::Mode;
@@ -89,6 +90,68 @@ fn test_mq_timedreceive() {
8990
assert_eq!(msg_to_send, str::from_utf8(&buf[0..len]).unwrap());
9091
}
9192

93+
#[test]
94+
fn test_mq_timedsend() {
95+
const MSG_SIZE: mq_attr_member_t = 32;
96+
let attr = MqAttr::new(0, 10, MSG_SIZE, 0);
97+
let mq_name = "/a_nix_test_queue_timedsend";
98+
99+
let oflag0 = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY;
100+
let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH;
101+
let r0 = mq_open(mq_name, oflag0, mode, Some(&attr));
102+
if let Err(Errno::ENOSYS) = r0 {
103+
println!("message queues not supported or module not loaded?");
104+
return;
105+
};
106+
let mqd0 = r0.unwrap();
107+
let msg_to_send = "msg_1";
108+
let abstime =
109+
clock_gettime(ClockId::CLOCK_REALTIME).unwrap() + TimeSpec::seconds(1);
110+
mq_timedsend(&mqd0, msg_to_send.as_bytes(), 1, &abstime).unwrap();
111+
112+
let oflag1 = MQ_OFlag::O_CREAT | MQ_OFlag::O_RDONLY;
113+
let mqd1 = mq_open(mq_name, oflag1, mode, Some(&attr)).unwrap();
114+
let mut buf = [0u8; 32];
115+
let mut prio = 0u32;
116+
let len = mq_receive(&mqd1, &mut buf, &mut prio).unwrap();
117+
assert_eq!(prio, 1);
118+
119+
mq_close(mqd1).unwrap();
120+
mq_close(mqd0).unwrap();
121+
assert_eq!(msg_to_send, str::from_utf8(&buf[0..len]).unwrap());
122+
mq_unlink(mq_name).unwrap();
123+
}
124+
125+
#[test]
126+
fn test_mq_timedsend_full() {
127+
const MSG_SIZE: mq_attr_member_t = 32;
128+
let attr = MqAttr::new(0, 10, MSG_SIZE, 0);
129+
let mq_name = "/a_nix_test_queue_fill";
130+
131+
let oflag0 = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY | MQ_OFlag::O_CLOEXEC;
132+
let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH;
133+
let r0 = mq_open(mq_name, oflag0, mode, Some(&attr));
134+
if let Err(Errno::ENOSYS) = r0 {
135+
println!("message queues not supported or module not loaded?");
136+
return;
137+
};
138+
let mqd0 = r0.unwrap();
139+
let msg_to_send = "msg_1";
140+
for _i in 0..10 {
141+
mq_send(&mqd0, msg_to_send.as_bytes(), 1).unwrap();
142+
}
143+
144+
let abstime =
145+
clock_gettime(ClockId::CLOCK_REALTIME).unwrap() + TimeSpec::seconds(1);
146+
assert_eq!(
147+
mq_timedsend(&mqd0, msg_to_send.as_bytes(), 1, &abstime),
148+
Err(Errno::ETIMEDOUT)
149+
);
150+
151+
mq_close(mqd0).unwrap();
152+
mq_unlink(mq_name).unwrap();
153+
}
154+
92155
#[test]
93156
fn test_mq_getattr() {
94157
use nix::mqueue::mq_getattr;

0 commit comments

Comments
 (0)