Skip to content

Commit b68db41

Browse files
committed
Merge #799
799: Fix nix on Dragonfly r=Susurrus a=mneumann This commit replaces pull request #684. It fixes building `nix` on DragonFly. All tests pass. This requires most recent libc to build: rust-lang/libc#851.
2 parents 291d618 + 709cbdf commit b68db41

File tree

9 files changed

+87
-42
lines changed

9 files changed

+87
-42
lines changed

Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ bitflags = "1.0"
1818
cfg-if = "0.1.0"
1919
void = "1.0.2"
2020

21+
[target.'cfg(target_os = "dragonfly")'.build-dependencies]
22+
gcc = "0.3"
23+
2124
[dev-dependencies]
2225
lazy_static = "1"
2326
rand = "0.3.8"

build.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#[cfg(target_os = "dragonfly")]
2+
extern crate gcc;
3+
4+
#[cfg(target_os = "dragonfly")]
5+
fn main() {
6+
gcc::Build::new()
7+
.file("src/errno_dragonfly.c")
8+
.compile("liberrno_dragonfly.a");
9+
}
10+
11+
#[cfg(not(target_os = "dragonfly"))]
12+
fn main() {}

src/errno.rs

+20-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use libc::{self, c_int};
1+
#[cfg(not(target_os = "dragonfly"))]
2+
use libc;
3+
use libc::c_int;
24
use std::{fmt, io, error};
35
use {Error, Result};
46

@@ -12,11 +14,23 @@ cfg_if! {
1214
libc::__error()
1315
}
1416
} else if #[cfg(target_os = "dragonfly")] {
15-
unsafe fn errno_location() -> *mut c_int {
16-
// FIXME: Replace with errno-dragonfly crate as this is no longer the correct
17-
// implementation.
18-
extern { fn __dfly_error() -> *mut c_int; }
19-
__dfly_error()
17+
// DragonFly uses a thread-local errno variable, but #[thread_local] is
18+
// feature-gated and not available in stable Rust as of this writing
19+
// (Rust 1.21.0). We have to use a C extension to access it
20+
// (src/errno_dragonfly.c).
21+
//
22+
// Tracking issue for `thread_local` stabilization:
23+
//
24+
// https://github.com/rust-lang/rust/issues/29594
25+
//
26+
// Once this becomes stable, we can remove build.rs,
27+
// src/errno_dragonfly.c, and use:
28+
//
29+
// extern { #[thread_local] static errno: c_int; }
30+
//
31+
#[link(name="errno_dragonfly", kind="static")]
32+
extern {
33+
pub fn errno_location() -> *mut c_int;
2034
}
2135
} else if #[cfg(any(target_os = "android",
2236
target_os = "netbsd",

src/errno_dragonfly.c

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include <errno.h>
2+
3+
int *errno_location() { return &errno; }

src/fcntl.rs

-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ libc_bitflags!(
4848
O_DIRECTORY;
4949
/// Implicitly follow each `write()` with an `fdatasync()`.
5050
#[cfg(any(target_os = "android",
51-
target_os = "dragonfly",
5251
target_os = "ios",
5352
target_os = "linux",
5453
target_os = "macos",

src/sys/socket/ffi.rs

+24-24
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,32 @@ pub use libc::{socket, listen, bind, accept, connect, setsockopt, sendto, recvfr
55

66
use libc::{c_int, c_void, socklen_t, ssize_t};
77

8-
#[cfg(not(target_os = "macos"))]
9-
use libc::size_t;
10-
11-
#[cfg(not(target_os = "linux"))]
12-
use libc::c_uint;
13-
148
use sys::uio::IoVec;
159

16-
#[cfg(target_os = "linux")]
17-
pub type type_of_cmsg_len = size_t;
18-
19-
#[cfg(not(target_os = "linux"))]
20-
pub type type_of_cmsg_len = socklen_t;
21-
22-
// OSX always aligns struct cmsghdr as if it were a 32-bit OS
23-
#[cfg(target_os = "macos")]
24-
pub type type_of_cmsg_data = c_uint;
25-
26-
#[cfg(not(target_os = "macos"))]
27-
pub type type_of_cmsg_data = size_t;
28-
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;
10+
cfg_if! {
11+
if #[cfg(target_os = "dragonfly")] {
12+
use libc::c_uint;
13+
pub type type_of_cmsg_len = socklen_t;
14+
pub type type_of_cmsg_data = c_int;
15+
pub type type_of_msg_iovlen = c_uint;
16+
} else if #[cfg(target_os = "linux")] {
17+
use libc::size_t;
18+
pub type type_of_cmsg_len = size_t;
19+
pub type type_of_cmsg_data = size_t;
20+
pub type type_of_msg_iovlen = size_t;
21+
} else if #[cfg(target_os = "macos")] {
22+
use libc::c_uint;
23+
pub type type_of_cmsg_len = socklen_t;
24+
// OSX always aligns struct cmsghdr as if it were a 32-bit OS
25+
pub type type_of_cmsg_data = c_uint;
26+
pub type type_of_msg_iovlen = c_uint;
27+
} else {
28+
use libc::{c_uint, size_t};
29+
pub type type_of_cmsg_len = socklen_t;
30+
pub type type_of_cmsg_data = size_t;
31+
pub type type_of_msg_iovlen = c_uint;
32+
}
33+
}
3434

3535
// Private because we don't expose any external functions that operate
3636
// directly on this type; we just use it internally at FFI boundaries.

src/unistd.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -630,8 +630,11 @@ pub fn execvp(filename: &CString, args: &[CString]) -> Result<Void> {
630630
///
631631
/// This function is similar to `execve`, except that the program to be executed
632632
/// is referenced as a file descriptor instead of a path.
633-
#[cfg(any(target_os = "android", target_os = "dragonfly", target_os = "freebsd",
634-
target_os = "netbsd", target_os = "openbsd", target_os = "linux"))]
633+
#[cfg(any(target_os = "android",
634+
target_os = "freebsd",
635+
target_os = "linux",
636+
target_os = "netbsd",
637+
target_os = "openbsd"))]
635638
#[inline]
636639
pub fn fexecve(fd: RawFd, args: &[CString], env: &[CString]) -> Result<Void> {
637640
let args_p = to_exec_array(args);

test/sys/mod.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
mod test_signal;
2-
#[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "ios",
3-
target_os = "netbsd", target_os = "macos", target_os = "linux"))]
2+
3+
// NOTE: DragonFly lacks a kernel-level implementation of Posix AIO as of
4+
// this writing. There is an user-level implementation, but whether aio
5+
// works or not heavily depends on which pthread implementation is chosen
6+
// by the user at link time. For this reason we do not want to run aio test
7+
// cases on DragonFly.
8+
#[cfg(any(target_os = "freebsd",
9+
target_os = "ios",
10+
target_os = "linux",
11+
target_os = "macos",
12+
target_os = "netbsd"))]
413
mod test_aio;
514
#[cfg(target_os = "linux")]
615
mod test_signalfd;
@@ -14,5 +23,6 @@ mod test_uio;
1423
#[cfg(target_os = "linux")]
1524
mod test_epoll;
1625
mod test_pthread;
17-
#[cfg(any(target_os = "linux", target_os = "android"))]
26+
#[cfg(any(target_os = "android",
27+
target_os = "linux"))]
1828
mod test_ptrace;

test/test_unistd.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -242,16 +242,17 @@ cfg_if!{
242242
if #[cfg(target_os = "android")] {
243243
execve_test_factory!(test_execve, execve, &CString::new("/system/bin/sh").unwrap());
244244
execve_test_factory!(test_fexecve, fexecve, File::open("/system/bin/sh").unwrap().into_raw_fd());
245-
} else if #[cfg(any(target_os = "dragonfly",
246-
target_os = "freebsd",
245+
} else if #[cfg(any(target_os = "freebsd",
246+
target_os = "linux",
247247
target_os = "netbsd",
248-
target_os = "openbsd",
249-
target_os = "linux", ))] {
248+
target_os = "openbsd"))] {
250249
execve_test_factory!(test_execve, execve, &CString::new("/bin/sh").unwrap());
251250
execve_test_factory!(test_fexecve, fexecve, File::open("/bin/sh").unwrap().into_raw_fd());
252-
} else if #[cfg(any(target_os = "ios", target_os = "macos", ))] {
251+
} else if #[cfg(any(target_os = "dragonfly",
252+
target_os = "ios",
253+
target_os = "macos"))] {
253254
execve_test_factory!(test_execve, execve, &CString::new("/bin/sh").unwrap());
254-
// No fexecve() on macos/ios.
255+
// No fexecve() on macos/ios and DragonFly.
255256
}
256257
}
257258

0 commit comments

Comments
 (0)