From 831ca990d2a55feb45aeaefc639298b7e181a6fa Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Wed, 13 Dec 2017 20:49:17 -0700 Subject: [PATCH] POSIX mqueue bindings for the BSDs Note that OpenBSD and OSX do not support POSIX message queues. --- libc-test/build.rs | 17 +++++++++++- src/unix/bsd/freebsdlike/dragonfly/mod.rs | 7 +++++ src/unix/bsd/freebsdlike/freebsd/mod.rs | 8 ++++++ src/unix/bsd/freebsdlike/mod.rs | 27 ++++++++++++++++++ src/unix/bsd/netbsdlike/netbsd/mod.rs | 34 +++++++++++++++++++++++ 5 files changed, 92 insertions(+), 1 deletion(-) diff --git a/libc-test/build.rs b/libc-test/build.rs index edf94d71..d6bc8814 100644 --- a/libc-test/build.rs +++ b/libc-test/build.rs @@ -268,6 +268,7 @@ fn main() { } if freebsd { + cfg.header("mqueue.h"); cfg.header("pthread_np.h"); cfg.header("sched.h"); cfg.header("ufs/ufs/quota.h"); @@ -278,6 +279,7 @@ fn main() { } if netbsd { + cfg.header("mqueue.h"); cfg.header("ufs/ufs/quota.h"); cfg.header("ufs/ufs/quota1.h"); cfg.header("sys/ioctl_compat.h"); @@ -293,6 +295,7 @@ fn main() { } if dragonfly { + cfg.header("mqueue.h"); cfg.header("ufs/ufs/quota.h"); cfg.header("pthread_np.h"); cfg.header("sys/ioctl_compat.h"); @@ -424,7 +427,9 @@ fn main() { "uuid_t" if dragonfly => true, n if n.starts_with("pthread") => true, // sem_t is a struct or pointer - "sem_t" if openbsd || freebsd || dragonfly || rumprun => true, + "sem_t" if openbsd || freebsd || dragonfly || netbsd => true, + // mqd_t is a pointer on FreeBSD and DragonFly + "mqd_t" if freebsd || dragonfly => true, // windows-isms n if n.starts_with("P") => true, @@ -590,6 +595,16 @@ fn main() { "shm_open" | "shm_unlink" | "syscall" | + "mq_open" | + "mq_close" | + "mq_getattr" | + "mq_notify" | + "mq_receive" | + "mq_send" | + "mq_setattr" | + "mq_timedreceive" | + "mq_timedsend" | + "mq_unlink" | "ptrace" | "sigaltstack" if rumprun => true, diff --git a/src/unix/bsd/freebsdlike/dragonfly/mod.rs b/src/unix/bsd/freebsdlike/dragonfly/mod.rs index 88708573..58d96dc8 100644 --- a/src/unix/bsd/freebsdlike/dragonfly/mod.rs +++ b/src/unix/bsd/freebsdlike/dragonfly/mod.rs @@ -72,6 +72,13 @@ s! { pub node: [u8; 6], } + pub struct mq_attr { + pub mq_flags: ::c_long, + pub mq_maxmsg: ::c_long, + pub mq_msgsize: ::c_long, + pub mq_curmsgs: ::c_long, + } + pub struct sigevent { pub sigev_notify: ::c_int, // The union is 8-byte in size, so it is aligned at a 8-byte offset. diff --git a/src/unix/bsd/freebsdlike/freebsd/mod.rs b/src/unix/bsd/freebsdlike/freebsd/mod.rs index 4a4323b0..693e7bea 100644 --- a/src/unix/bsd/freebsdlike/freebsd/mod.rs +++ b/src/unix/bsd/freebsdlike/freebsd/mod.rs @@ -62,6 +62,14 @@ s! { pub ip6: *mut ::in6_addr, } + pub struct mq_attr { + pub mq_flags: ::c_long, + pub mq_maxmsg: ::c_long, + pub mq_msgsize: ::c_long, + pub mq_curmsgs: ::c_long, + __reserved: [::c_long; 4] + } + pub struct sigevent { pub sigev_notify: ::c_int, pub sigev_signo: ::c_int, diff --git a/src/unix/bsd/freebsdlike/mod.rs b/src/unix/bsd/freebsdlike/mod.rs index 215acee6..983c0cc3 100644 --- a/src/unix/bsd/freebsdlike/mod.rs +++ b/src/unix/bsd/freebsdlike/mod.rs @@ -2,6 +2,7 @@ pub type dev_t = u32; pub type mode_t = u16; pub type pthread_attr_t = *mut ::c_void; pub type rlim_t = i64; +pub type mqd_t = *mut ::c_void; pub type pthread_mutex_t = *mut ::c_void; pub type pthread_mutexattr_t = *mut ::c_void; pub type pthread_cond_t = *mut ::c_void; @@ -978,6 +979,32 @@ extern { groups: *mut ::gid_t, ngroups: *mut ::c_int) -> ::c_int; pub fn initgroups(name: *const ::c_char, basegid: ::gid_t) -> ::c_int; + pub fn mq_open(name: *const ::c_char, oflag: ::c_int, ...) -> ::mqd_t; + pub fn mq_close(mqd: ::mqd_t) -> ::c_int; + pub fn mq_getattr(mqd: ::mqd_t, attr: *mut ::mq_attr) -> ::c_int; + pub fn mq_notify(mqd: ::mqd_t, notification: *const ::sigevent) -> ::c_int; + pub fn mq_receive(mqd: ::mqd_t, + msg_ptr: *mut ::c_char, + msg_len: ::size_t, + msq_prio: *mut ::c_uint) -> ::ssize_t; + pub fn mq_send(mqd: ::mqd_t, + msg_ptr: *const ::c_char, + msg_len: ::size_t, + msq_prio: ::c_uint) -> ::c_int; + pub fn mq_setattr(mqd: ::mqd_t, + newattr: *const ::mq_attr, + oldattr: *mut ::mq_attr) -> ::c_int; + pub fn mq_timedreceive(mqd: ::mqd_t, + msg_ptr: *mut ::c_char, + msg_len: ::size_t, + msq_prio: *mut ::c_uint, + abs_timeout: *const ::timespec) -> ::ssize_t; + pub fn mq_timedsend(mqd: ::mqd_t, + msg_ptr: *const ::c_char, + msg_len: ::size_t, + msq_prio: ::c_uint, + abs_timeout: *const ::timespec) -> ::c_int; + pub fn mq_unlink(name: *const ::c_char) -> ::c_int; } #[link(name = "util")] diff --git a/src/unix/bsd/netbsdlike/netbsd/mod.rs b/src/unix/bsd/netbsdlike/netbsd/mod.rs index 45b72820..bc4256d3 100644 --- a/src/unix/bsd/netbsdlike/netbsd/mod.rs +++ b/src/unix/bsd/netbsdlike/netbsd/mod.rs @@ -7,6 +7,7 @@ pub type blksize_t = ::int32_t; pub type fsblkcnt_t = ::uint64_t; pub type fsfilcnt_t = ::uint64_t; pub type idtype_t = ::c_int; +pub type mqd_t = ::c_int; s! { pub struct aiocb { @@ -46,6 +47,13 @@ s! { __unused8: *mut ::c_void, } + pub struct mq_attr { + pub mq_flags: ::c_long, + pub mq_maxmsg: ::c_long, + pub mq_msgsize: ::c_long, + pub mq_curmsgs: ::c_long, + } + pub struct sigevent { pub sigev_notify: ::c_int, pub sigev_signo: ::c_int, @@ -988,6 +996,32 @@ extern { flags: ::c_int, data: *mut ::c_void, size: ::size_t) -> ::c_int; + pub fn mq_open(name: *const ::c_char, oflag: ::c_int, ...) -> ::mqd_t; + pub fn mq_close(mqd: ::mqd_t) -> ::c_int; + pub fn mq_getattr(mqd: ::mqd_t, attr: *mut ::mq_attr) -> ::c_int; + pub fn mq_notify(mqd: ::mqd_t, notification: *const ::sigevent) -> ::c_int; + pub fn mq_receive(mqd: ::mqd_t, + msg_ptr: *mut ::c_char, + msg_len: ::size_t, + msq_prio: *mut ::c_uint) -> ::ssize_t; + pub fn mq_send(mqd: ::mqd_t, + msg_ptr: *const ::c_char, + msg_len: ::size_t, + msq_prio: ::c_uint) -> ::c_int; + pub fn mq_setattr(mqd: ::mqd_t, + newattr: *const ::mq_attr, + oldattr: *mut ::mq_attr) -> ::c_int; + pub fn mq_timedreceive(mqd: ::mqd_t, + msg_ptr: *mut ::c_char, + msg_len: ::size_t, + msq_prio: *mut ::c_uint, + abs_timeout: *const ::timespec) -> ::ssize_t; + pub fn mq_timedsend(mqd: ::mqd_t, + msg_ptr: *const ::c_char, + msg_len: ::size_t, + msq_prio: ::c_uint, + abs_timeout: *const ::timespec) -> ::c_int; + pub fn mq_unlink(name: *const ::c_char) -> ::c_int; pub fn ptrace(request: ::c_int, pid: ::pid_t, addr: *mut ::c_void,