Skip to content

Commit 087aece

Browse files
committed
Merge #688
688: Support for OpenBSD r=Susurrus Fixes #685 These changes get nix building on OpenBSD 6.1. There is one failing test that I want a little guidance on: ``` error[E0308]: mismatched types --> src/sys/event.rs:333:30 | 333 | assert!(expected.data == actual.data()); | ^^^^^^^^^^^^^ expected i64, found isize ``` `KEvent::data` is: ``` pub fn data(&self) -> intptr_t { self.kevent.data as intptr_t } ``` I assume the test should be updated to cast to the expected type but wanted to confirm that before making the change.
2 parents 6334f55 + 0fbd223 commit 087aece

File tree

7 files changed

+197
-121
lines changed

7 files changed

+197
-121
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
2424
- Exposed `unistd::setresuid` and `unistd::setresgid` on FreeBSD and OpenBSD
2525
([#721](https://github.com/nix-rust/nix/pull/721))
2626

27+
# Fixed
28+
- Fix compilation and tests for OpenBSD targets
29+
([#688](https://github.com/nix-rust/nix/pull/688))
30+
2731
## [0.9.0] 2017-07-23
2832

2933
### Added

nix-test/src/const.c

+25
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,31 @@ get_int_const(const char* err) {
209209
GET_CONST(ECANCELED);
210210
#endif
211211

212+
#if defined(__OpenBSD__)
213+
GET_CONST(EAUTH);
214+
GET_CONST(EBADRPC);
215+
GET_CONST(ECANCELED);
216+
GET_CONST(EDQUOT);
217+
GET_CONST(EFTYPE);
218+
GET_CONST(EILSEQ);
219+
GET_CONST(EIPSEC);
220+
GET_CONST(EMEDIUMTYPE);
221+
GET_CONST(ENEEDAUTH);
222+
GET_CONST(ENOATTR);
223+
GET_CONST(ENOMEDIUM);
224+
GET_CONST(ENOTSUP);
225+
GET_CONST(EOPNOTSUPP);
226+
GET_CONST(EOVERFLOW);
227+
GET_CONST(EPROCLIM);
228+
GET_CONST(EPROCUNAVAIL);
229+
GET_CONST(EPROGMISMATCH);
230+
GET_CONST(EPROGUNAVAIL);
231+
GET_CONST(EREMOTE);
232+
GET_CONST(ERPCMISMATCH);
233+
GET_CONST(ESTALE);
234+
GET_CONST(EUSERS);
235+
#endif
236+
212237
#ifdef DARWIN
213238
GET_CONST(EPWROFF);
214239
GET_CONST(EDEVERR);

src/sys/event.rs

+24-14
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,16 @@ pub struct KEvent {
1818
kevent: libc::kevent,
1919
}
2020

21-
#[cfg(any(target_os = "openbsd", target_os = "freebsd",
22-
target_os = "dragonfly", target_os = "macos",
23-
target_os = "ios"))]
21+
#[cfg(any(target_os = "dragonfly", target_os = "freebsd",
22+
target_os = "ios", target_os = "macos",
23+
target_os = "openbsd"))]
2424
type type_of_udata = *mut libc::c_void;
25-
#[cfg(any(target_os = "openbsd", target_os = "freebsd",
26-
target_os = "dragonfly", target_os = "macos",
27-
target_os = "ios"))]
25+
#[cfg(any(target_os = "dragonfly", target_os = "freebsd",
26+
target_os = "ios", target_os = "macos"))]
2827
type type_of_data = libc::intptr_t;
2928
#[cfg(any(target_os = "netbsd"))]
3029
type type_of_udata = intptr_t;
31-
#[cfg(any(target_os = "netbsd"))]
30+
#[cfg(any(target_os = "netbsd", target_os = "openbsd"))]
3231
type type_of_data = libc::int64_t;
3332

3433
#[cfg(not(target_os = "netbsd"))]
@@ -78,17 +77,26 @@ pub enum EventFilter {
7877
EVFILT_TIMER = libc::EVFILT_TIMER,
7978
}
8079

81-
#[cfg(any(target_os = "macos", target_os = "ios",
82-
target_os = "freebsd", target_os = "dragonfly"))]
80+
#[cfg(any(target_os = "dragonfly", target_os = "freebsd",
81+
target_os = "ios", target_os = "macos",
82+
target_os = "openbsd"))]
8383
pub type type_of_event_flag = u16;
84-
#[cfg(any(target_os = "netbsd", target_os = "openbsd"))]
84+
#[cfg(any(target_os = "netbsd"))]
8585
pub type type_of_event_flag = u32;
8686
libc_bitflags!{
8787
pub flags EventFlag: type_of_event_flag {
8888
EV_ADD,
8989
EV_CLEAR,
9090
EV_DELETE,
9191
EV_DISABLE,
92+
// No released version of OpenBSD supports EV_DISPATCH or EV_RECEIPT.
93+
// These have been commited to the -current branch though and are
94+
// expected to be part of the OpenBSD 6.2 release in Nov 2017.
95+
// See: https://marc.info/?l=openbsd-tech&m=149621427511219&w=2
96+
// https://github.com/rust-lang/libc/pull/613
97+
#[cfg(any(target_os = "dragonfly", target_os = "freebsd",
98+
target_os = "ios", target_os = "macos",
99+
target_os = "netbsd"))]
92100
EV_DISPATCH,
93101
#[cfg(target_os = "freebsd")]
94102
EV_DROP,
@@ -105,7 +113,9 @@ libc_bitflags!{
105113
EV_OOBAND,
106114
#[cfg(any(target_os = "macos", target_os = "ios"))]
107115
EV_POLL,
108-
#[cfg(not(target_os = "openbsd"))]
116+
#[cfg(any(target_os = "dragonfly", target_os = "freebsd",
117+
target_os = "ios", target_os = "macos",
118+
target_os = "netbsd"))]
109119
EV_RECEIPT,
110120
EV_SYSFLAGS,
111121
}
@@ -315,21 +325,21 @@ fn test_struct_kevent() {
315325

316326
let expected = libc::kevent{ident: 0xdeadbeef,
317327
filter: libc::EVFILT_READ,
318-
flags: libc::EV_DISPATCH | libc::EV_ADD,
328+
flags: libc::EV_ONESHOT | libc::EV_ADD,
319329
fflags: libc::NOTE_CHILD | libc::NOTE_EXIT,
320330
data: 0x1337,
321331
udata: udata as type_of_udata};
322332
let actual = KEvent::new(0xdeadbeef,
323333
EventFilter::EVFILT_READ,
324-
EV_DISPATCH | EV_ADD,
334+
EV_ONESHOT | EV_ADD,
325335
NOTE_CHILD | NOTE_EXIT,
326336
0x1337,
327337
udata);
328338
assert!(expected.ident == actual.ident());
329339
assert!(expected.filter == actual.filter() as type_of_event_filter);
330340
assert!(expected.flags == actual.flags().bits());
331341
assert!(expected.fflags == actual.fflags().bits());
332-
assert!(expected.data == actual.data());
342+
assert!(expected.data == actual.data() as type_of_data);
333343
assert!(expected.udata == actual.udata() as type_of_udata);
334344
assert!(mem::size_of::<libc::kevent>() == mem::size_of::<KEvent>());
335345
}

src/sys/signal.rs

+103-90
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33

44
use libc;
55
use {Errno, Error, Result};
6-
use std::fmt;
7-
use std::fmt::Debug;
86
use std::mem;
97
#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
108
use std::os::unix::io::RawFd;
119
use std::ptr;
1210

11+
#[cfg(not(target_os = "openbsd"))]
12+
pub use self::sigevent::*;
13+
1314
// Currently there is only one definition of c_int in libc, as well as only one
1415
// type for signal constants.
1516
// We would prefer to use the libc::c_int alias in the repr attribute. Unfortunately
@@ -488,102 +489,114 @@ pub enum SigevNotify {
488489
si_value: libc::intptr_t },
489490
}
490491

491-
/// Used to request asynchronous notification of the completion of certain
492-
/// events, such as POSIX AIO and timers.
493-
#[repr(C)]
494-
pub struct SigEvent {
495-
sigevent: libc::sigevent
496-
}
492+
#[cfg(not(target_os = "openbsd"))]
493+
mod sigevent {
494+
use libc;
495+
use std::mem;
496+
use std::ptr;
497+
use std::fmt::{self, Debug};
498+
use super::SigevNotify;
499+
#[cfg(any(target_os = "freebsd", target_os = "linux"))]
500+
use super::type_of_thread_id;
501+
502+
/// Used to request asynchronous notification of the completion of certain
503+
/// events, such as POSIX AIO and timers.
504+
#[repr(C)]
505+
pub struct SigEvent {
506+
sigevent: libc::sigevent
507+
}
508+
509+
impl SigEvent {
510+
/// **Note:** this constructor does not allow the user to set the
511+
/// `sigev_notify_kevent_flags` field. That's considered ok because on FreeBSD
512+
/// at least those flags don't do anything useful. That field is part of a
513+
/// union that shares space with the more genuinely useful fields.
514+
///
515+
/// **Note:** This constructor also doesn't allow the caller to set the
516+
/// `sigev_notify_function` or `sigev_notify_attributes` fields, which are
517+
/// required for `SIGEV_THREAD`. That's considered ok because on no operating
518+
/// system is `SIGEV_THREAD` the most efficient way to deliver AIO
519+
/// notification. FreeBSD and DragonFly BSD programs should prefer `SIGEV_KEVENT`.
520+
/// Linux, Solaris, and portable programs should prefer `SIGEV_THREAD_ID` or
521+
/// `SIGEV_SIGNAL`. That field is part of a union that shares space with the
522+
/// more genuinely useful `sigev_notify_thread_id`
523+
pub fn new(sigev_notify: SigevNotify) -> SigEvent {
524+
let mut sev = unsafe { mem::zeroed::<libc::sigevent>()};
525+
sev.sigev_notify = match sigev_notify {
526+
SigevNotify::SigevNone => libc::SIGEV_NONE,
527+
SigevNotify::SigevSignal{..} => libc::SIGEV_SIGNAL,
528+
#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
529+
SigevNotify::SigevKevent{..} => libc::SIGEV_KEVENT,
530+
#[cfg(target_os = "freebsd")]
531+
SigevNotify::SigevThreadId{..} => libc::SIGEV_THREAD_ID,
532+
#[cfg(all(target_os = "linux", target_env = "gnu", not(target_arch = "mips")))]
533+
SigevNotify::SigevThreadId{..} => libc::SIGEV_THREAD_ID,
534+
#[cfg(any(all(target_os = "linux", target_env = "musl"), target_arch = "mips"))]
535+
SigevNotify::SigevThreadId{..} => 4 // No SIGEV_THREAD_ID defined
536+
};
537+
sev.sigev_signo = match sigev_notify {
538+
SigevNotify::SigevSignal{ signal, .. } => signal as libc::c_int,
539+
#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
540+
SigevNotify::SigevKevent{ kq, ..} => kq,
541+
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
542+
SigevNotify::SigevThreadId{ signal, .. } => signal as libc::c_int,
543+
_ => 0
544+
};
545+
sev.sigev_value.sival_ptr = match sigev_notify {
546+
SigevNotify::SigevNone => ptr::null_mut::<libc::c_void>(),
547+
SigevNotify::SigevSignal{ si_value, .. } => si_value as *mut libc::c_void,
548+
#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
549+
SigevNotify::SigevKevent{ udata, .. } => udata as *mut libc::c_void,
550+
#[cfg(any(target_os = "freebsd", target_os = "linux"))]
551+
SigevNotify::SigevThreadId{ si_value, .. } => si_value as *mut libc::c_void,
552+
};
553+
SigEvent::set_tid(&mut sev, &sigev_notify);
554+
SigEvent{sigevent: sev}
555+
}
497556

498-
impl SigEvent {
499-
// Note: this constructor does not allow the user to set the
500-
// sigev_notify_kevent_flags field. That's considered ok because on FreeBSD
501-
// at least those flags don't do anything useful. That field is part of a
502-
// union that shares space with the more genuinely useful
503-
// Note: This constructor also doesn't allow the caller to set the
504-
// sigev_notify_function or sigev_notify_attributes fields, which are
505-
// required for SIGEV_THREAD. That's considered ok because on no operating
506-
// system is SIGEV_THREAD the most efficient way to deliver AIO
507-
// notification. FreeBSD and Dragonfly programs should prefer SIGEV_KEVENT.
508-
// Linux, Solaris, and portable programs should prefer SIGEV_THREAD_ID or
509-
// SIGEV_SIGNAL. That field is part of a union that shares space with the
510-
// more genuinely useful sigev_notify_thread_id
511-
pub fn new(sigev_notify: SigevNotify) -> SigEvent {
512-
let mut sev = unsafe { mem::zeroed::<libc::sigevent>()};
513-
sev.sigev_notify = match sigev_notify {
514-
SigevNotify::SigevNone => libc::SIGEV_NONE,
515-
SigevNotify::SigevSignal{..} => libc::SIGEV_SIGNAL,
516-
#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
517-
SigevNotify::SigevKevent{..} => libc::SIGEV_KEVENT,
518-
#[cfg(target_os = "freebsd")]
519-
SigevNotify::SigevThreadId{..} => libc::SIGEV_THREAD_ID,
520-
#[cfg(all(target_os = "linux", target_env = "gnu", not(target_arch = "mips")))]
521-
SigevNotify::SigevThreadId{..} => libc::SIGEV_THREAD_ID,
522-
#[cfg(any(all(target_os = "linux", target_env = "musl"), target_arch = "mips"))]
523-
SigevNotify::SigevThreadId{..} => 4 // No SIGEV_THREAD_ID defined
524-
};
525-
sev.sigev_signo = match sigev_notify {
526-
SigevNotify::SigevSignal{ signal, .. } => signal as libc::c_int,
527-
#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
528-
SigevNotify::SigevKevent{ kq, ..} => kq,
529-
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
530-
SigevNotify::SigevThreadId{ signal, .. } => signal as libc::c_int,
531-
_ => 0
532-
};
533-
sev.sigev_value.sival_ptr = match sigev_notify {
534-
SigevNotify::SigevNone => ptr::null_mut::<libc::c_void>(),
535-
SigevNotify::SigevSignal{ si_value, .. } => si_value as *mut libc::c_void,
536-
#[cfg(any(target_os = "dragonfly", target_os = "freebsd"))]
537-
SigevNotify::SigevKevent{ udata, .. } => udata as *mut libc::c_void,
538-
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
539-
SigevNotify::SigevThreadId{ si_value, .. } => si_value as *mut libc::c_void,
540-
};
541-
SigEvent::set_tid(&mut sev, &sigev_notify);
542-
SigEvent{sigevent: sev}
543-
}
557+
#[cfg(any(target_os = "freebsd", target_os = "linux"))]
558+
fn set_tid(sev: &mut libc::sigevent, sigev_notify: &SigevNotify) {
559+
sev.sigev_notify_thread_id = match sigev_notify {
560+
&SigevNotify::SigevThreadId { thread_id, .. } => thread_id,
561+
_ => 0 as type_of_thread_id
562+
};
563+
}
544564

545-
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
546-
fn set_tid(sev: &mut libc::sigevent, sigev_notify: &SigevNotify) {
547-
sev.sigev_notify_thread_id = match sigev_notify {
548-
&SigevNotify::SigevThreadId { thread_id, .. } => thread_id,
549-
_ => 0 as type_of_thread_id
550-
};
551-
}
565+
#[cfg(not(any(target_os = "freebsd", target_os = "linux")))]
566+
fn set_tid(_sev: &mut libc::sigevent, _sigev_notify: &SigevNotify) {
567+
}
552568

553-
#[cfg(not(any(target_os = "freebsd", target_os = "linux")))]
554-
fn set_tid(_sev: &mut libc::sigevent, _sigev_notify: &SigevNotify) {
569+
pub fn sigevent(&self) -> libc::sigevent {
570+
self.sigevent
571+
}
555572
}
556573

557-
pub fn sigevent(&self) -> libc::sigevent {
558-
self.sigevent
559-
}
560-
}
574+
impl Debug for SigEvent {
575+
#[cfg(any(target_os = "freebsd", target_os = "linux"))]
576+
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
577+
fmt.debug_struct("SigEvent")
578+
.field("sigev_notify", &self.sigevent.sigev_notify)
579+
.field("sigev_signo", &self.sigevent.sigev_signo)
580+
.field("sigev_value", &self.sigevent.sigev_value.sival_ptr)
581+
.field("sigev_notify_thread_id",
582+
&self.sigevent.sigev_notify_thread_id)
583+
.finish()
584+
}
561585

562-
impl Debug for SigEvent {
563-
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
564-
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
565-
fmt.debug_struct("SigEvent")
566-
.field("sigev_notify", &self.sigevent.sigev_notify)
567-
.field("sigev_signo", &self.sigevent.sigev_signo)
568-
.field("sigev_value", &self.sigevent.sigev_value.sival_ptr)
569-
.field("sigev_notify_thread_id",
570-
&self.sigevent.sigev_notify_thread_id)
571-
.finish()
572-
}
573-
574-
#[cfg(not(any(target_os = "linux", target_os = "freebsd")))]
575-
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
576-
fmt.debug_struct("SigEvent")
577-
.field("sigev_notify", &self.sigevent.sigev_notify)
578-
.field("sigev_signo", &self.sigevent.sigev_signo)
579-
.field("sigev_value", &self.sigevent.sigev_value.sival_ptr)
580-
.finish()
586+
#[cfg(not(any(target_os = "freebsd", target_os = "linux")))]
587+
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
588+
fmt.debug_struct("SigEvent")
589+
.field("sigev_notify", &self.sigevent.sigev_notify)
590+
.field("sigev_signo", &self.sigevent.sigev_signo)
591+
.field("sigev_value", &self.sigevent.sigev_value.sival_ptr)
592+
.finish()
593+
}
581594
}
582-
}
583595

584-
impl<'a> From<&'a libc::sigevent> for SigEvent {
585-
fn from(sigevent: &libc::sigevent) -> Self {
586-
SigEvent{ sigevent: sigevent.clone() }
596+
impl<'a> From<&'a libc::sigevent> for SigEvent {
597+
fn from(sigevent: &libc::sigevent) -> Self {
598+
SigEvent{ sigevent: sigevent.clone() }
599+
}
587600
}
588601
}
589602

src/sys/socket/ffi.rs

+15-4
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33

44
pub use libc::{socket, listen, bind, accept, connect, setsockopt, sendto, recvfrom, getsockname, getpeername, recv, send};
55

6-
use libc::{c_int, c_void, socklen_t, size_t, ssize_t};
6+
use libc::{c_int, c_void, socklen_t, ssize_t};
77

8-
#[cfg(target_os = "macos")]
8+
#[cfg(not(target_os = "macos"))]
9+
use libc::size_t;
10+
11+
#[cfg(not(target_os = "linux"))]
912
use libc::c_uint;
1013

1114
use sys::uio::IoVec;
@@ -23,19 +26,27 @@ pub type type_of_cmsg_data = c_uint;
2326
#[cfg(not(target_os = "macos"))]
2427
pub type type_of_cmsg_data = size_t;
2528

29+
#[cfg(target_os = "linux")]
30+
pub type type_of_msg_iovlen = size_t;
31+
32+
#[cfg(not(target_os = "linux"))]
33+
pub type type_of_msg_iovlen = c_uint;
34+
2635
// Private because we don't expose any external functions that operate
2736
// directly on this type; we just use it internally at FFI boundaries.
2837
// Note that in some cases we store pointers in *const fields that the
2938
// kernel will proceed to mutate, so users should be careful about the
3039
// actual mutability of data pointed to by this structure.
40+
//
41+
// FIXME: Replace these structs with the ones defined in libc
3142
#[repr(C)]
3243
pub struct msghdr<'a> {
3344
pub msg_name: *const c_void,
3445
pub msg_namelen: socklen_t,
3546
pub msg_iov: *const IoVec<&'a [u8]>,
36-
pub msg_iovlen: size_t,
47+
pub msg_iovlen: type_of_msg_iovlen,
3748
pub msg_control: *const c_void,
38-
pub msg_controllen: size_t,
49+
pub msg_controllen: type_of_cmsg_len,
3950
pub msg_flags: c_int,
4051
}
4152

0 commit comments

Comments
 (0)