Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose mqueue functions for all supported OSes #834

Merged
merged 1 commit into from
Jan 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
([#826](https://github.com/nix-rust/nix/pull/826))

### Changed
- Exposed the `mqueue` module for all supported operating systems.
([#834](https://github.com/nix-rust/nix/pull/834))
- Use native `pipe2` on all BSD targets. Users should notice no difference.
([#777](https://github.com/nix-rust/nix/pull/777))
- Renamed existing `ptrace` wrappers to encourage namespacing ([#692](https://github.com/nix-rust/nix/pull/692))
Expand Down
4 changes: 4 additions & 0 deletions src/errno.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ impl ErrnoSentinel for i64 {
fn sentinel() -> Self { -1 }
}

impl ErrnoSentinel for *mut libc::c_void {
fn sentinel() -> Self { (-1 as isize) as *mut libc::c_void }
}

impl error::Error for Errno {
fn description(&self) -> &str {
self.desc()
Expand Down
6 changes: 5 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ pub mod fcntl;
#[cfg(any(target_os = "linux", target_os = "android"))]
pub mod mount;

#[cfg(target_os = "linux")]
#[cfg(any(target_os = "dragonfly",
target_os = "freebsd",
target_os = "fushsia",
target_os = "linux",
target_os = "netbsd"))]
pub mod mqueue;

pub mod pty;
Expand Down
4 changes: 2 additions & 2 deletions src/mqueue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use Result;
use errno::Errno;

use libc::{self, c_char, c_long, mode_t, mqd_t, size_t};
use libc::{self, c_char, c_long, mqd_t, size_t};
use std::ffi::CString;
use sys::stat::Mode;
use std::mem;
Expand Down Expand Up @@ -76,7 +76,7 @@ pub fn mq_open(name: &CString,
Some(mq_attr) => unsafe {
libc::mq_open(name.as_ptr(),
oflag.bits(),
mode.bits() as mode_t,
mode.bits() as libc::c_int,
&mq_attr.mq_attr as *const libc::mq_attr)
},
None => unsafe { libc::mq_open(name.as_ptr(), oflag.bits()) },
Expand Down
6 changes: 5 additions & 1 deletion test/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ extern crate tempfile;

mod sys;
mod test_fcntl;
#[cfg(target_os = "linux")]
#[cfg(any(target_os = "dragonfly",
target_os = "freebsd",
target_os = "fushsia",
target_os = "linux",
target_os = "netbsd"))]
mod test_mq;
mod test_net;
mod test_nix_path;
Expand Down
54 changes: 43 additions & 11 deletions test/test_mq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,19 @@ fn test_mq_send_and_receive() {
let attr = MqAttr::new(0, 10, MSG_SIZE, 0);
let mq_name= &CString::new(b"/a_nix_test_queue".as_ref()).unwrap();

let mqd0 = mq_open(mq_name, MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY,
Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH,
Some(&attr)).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(Sys(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 mqd1 = mq_open(mq_name, MQ_OFlag::O_CREAT | MQ_OFlag::O_RDONLY,
Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH,
Some(&attr)).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 len = mq_receive(mqd1, &mut buf, &mut prio).unwrap();
Expand All @@ -40,7 +44,15 @@ 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(b"/attr_test_get_attr".as_ref()).unwrap();
let mqd = mq_open(mq_name, MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY, Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH, Some(&initial_attr)).unwrap();
let oflag = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY;
let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH;
let r = mq_open(mq_name, oflag, mode, Some(&initial_attr));
if let Err(Sys(ENOSYS)) = r {
println!("message queues not supported or module not loaded?");
return;
};
let mqd = r.unwrap();

let read_attr = mq_getattr(mqd);
assert!(read_attr.unwrap() == initial_attr);
mq_close(mqd).unwrap();
Expand All @@ -53,7 +65,14 @@ 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(b"/attr_test_get_attr".as_ref()).unwrap();
let mqd = mq_open(mq_name, MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY, Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH, Some(&initial_attr)).unwrap();
let oflag = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY;
let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH;
let r = mq_open(mq_name, oflag, mode, Some(&initial_attr));
if let Err(Sys(ENOSYS)) = r {
println!("message queues not supported or module not loaded?");
return;
};
let mqd = r.unwrap();

let new_attr = MqAttr::new(0, 20, MSG_SIZE * 2, 100);
let old_attr = mq_setattr(mqd, &new_attr);
Expand Down Expand Up @@ -81,7 +100,14 @@ 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(b"/attr_test_get_attr".as_ref()).unwrap();
let mqd = mq_open(mq_name, MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY, Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH, Some(&initial_attr)).unwrap();
let oflag = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY;
let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH;
let r = mq_open(mq_name, oflag, mode, Some(&initial_attr));
if let Err(Sys(ENOSYS)) = r {
println!("message queues not supported or module not loaded?");
return;
};
let mqd = r.unwrap();
mq_set_nonblock(mqd).unwrap();
let new_attr = mq_getattr(mqd);
assert!(new_attr.unwrap().flags() == MQ_OFlag::O_NONBLOCK.bits() as c_long);
Expand All @@ -97,7 +123,14 @@ fn test_mq_unlink() {
let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0);
let mq_name_opened = &CString::new(b"/mq_unlink_test".as_ref()).unwrap();
let mq_name_not_opened = &CString::new(b"/mq_unlink_test".as_ref()).unwrap();
let mqd = mq_open(mq_name_opened, MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY, Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH, Some(&initial_attr)).unwrap();
let oflag = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY;
let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH;
let r = mq_open(mq_name_opened, oflag, mode, Some(&initial_attr));
if let Err(Sys(ENOSYS)) = r {
println!("message queues not supported or module not loaded?");
return;
};
let mqd = r.unwrap();

let res_unlink = mq_unlink(mq_name_opened);
assert!(res_unlink == Ok(()) );
Expand All @@ -108,5 +141,4 @@ fn test_mq_unlink() {
mq_close(mqd).unwrap();
let res_unlink_after_close = mq_unlink(mq_name_opened);
assert!(res_unlink_after_close == Err(Sys(ENOENT)) );

}