From 07d3a0daccc4d9b3fa339d510b5b5e5eb190c2ee Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 30 Oct 2015 10:21:32 -0700 Subject: Add more bindings for signals and select/pselect --- libc-test/build.rs | 1 + src/dox.rs | 21 +++++++++++++ src/lib.rs | 2 +- src/macros.rs | 18 +++++++++++ src/unix/bsd/mod.rs | 53 ++++++++++++++++++++++++++++++-- src/unix/mod.rs | 19 ++++++++++++ src/unix/notbsd/android/mod.rs | 2 ++ src/unix/notbsd/linux/mips.rs | 4 ++- src/unix/notbsd/linux/notmips/mod.rs | 4 ++- src/unix/notbsd/mod.rs | 59 ++++++++++++++++++++++++++++++++++++ 10 files changed, 178 insertions(+), 5 deletions(-) diff --git a/libc-test/build.rs b/libc-test/build.rs index 4ee2ca6212..90784f3ec0 100644 --- a/libc-test/build.rs +++ b/libc-test/build.rs @@ -116,6 +116,7 @@ fn main() { match ty { // Just pass all these through, no need for a "struct" prefix "FILE" | + "fd_set" | "DIR" => ty.to_string(), // Fixup a few types on windows that don't actually exist. diff --git a/src/dox.rs b/src/dox.rs index 9432b88219..10e39348f8 100644 --- a/src/dox.rs +++ b/src/dox.rs @@ -5,6 +5,7 @@ mod imp { pub use std::option::Option; pub use std::clone::Clone; pub use std::marker::Copy; + pub use std::mem; } #[cfg(dox)] @@ -43,6 +44,22 @@ mod imp { ) } + #[lang = "div"] + pub trait Div { + type Output; + fn div(self, rhs: RHS) -> Self::Output; + } + + macro_rules! impl_div { + ($($i:ident)*) => ($( + impl Div<$i> for $i { + type Output = $i; + fn div(self, rhs: $i) -> $i { self / rhs } + } + )*) + } + each_int!(impl_div); + #[lang = "shl"] pub trait Shl { type Output; @@ -106,4 +123,8 @@ mod imp { )*) } each_int!(impl_bitor); + + pub mod mem { + pub fn size_of_val(_: &T) -> usize { 4 } + } } diff --git a/src/lib.rs b/src/lib.rs index 797c5394f9..6a5ae86b60 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,7 +10,7 @@ //! Crate docs -#![allow(bad_style, raw_pointer_derive, improper_ctypes)] +#![allow(bad_style, raw_pointer_derive, overflowing_literals, improper_ctypes)] #![cfg_attr(dox, feature(no_core, lang_items))] #![cfg_attr(dox, no_core)] #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", diff --git a/src/macros.rs b/src/macros.rs index bb5d9eeadd..7cd8a243c5 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -47,6 +47,24 @@ macro_rules! s { )*) } +macro_rules! f { + ($(pub fn $i:ident($($arg:ident: $argty:ty),*) -> $ret:ty { + $($body:stmt);* + })*) => ($( + #[inline] + #[cfg(not(dox))] + pub unsafe extern fn $i($($arg: $argty),*) -> $ret { + $($body);* + } + + #[cfg(dox)] + #[allow(dead_code)] + pub unsafe extern fn $i($($arg: $argty),*) -> $ret { + loop {} + } + )*) +} + macro_rules! __item { ($i:item) => ($i) } diff --git a/src/unix/bsd/mod.rs b/src/unix/bsd/mod.rs index 8c8460ef2d..ca738062b0 100644 --- a/src/unix/bsd/mod.rs +++ b/src/unix/bsd/mod.rs @@ -62,20 +62,69 @@ s! { pub ifa_dstaddr: *mut ::sockaddr, pub ifa_data: *mut ::c_void } + + pub struct fd_set { + fds_bits: [i32; FD_SETSIZE / 32], + } } -pub const FIOCLEX: c_ulong = 0x20006601; -pub const FIONBIO: ::c_int = 0x8004667e; +pub const FIOCLEX: ::c_ulong = 0x20006601; +pub const FIONBIO: ::c_ulong = 0x8004667e; pub const SA_ONSTACK: ::c_int = 0x0001; pub const SA_SIGINFO: ::c_int = 0x0040; +pub const SA_RESTART: ::c_int = 0x0002; +pub const SA_RESETHAND: ::c_int = 0x0004; +pub const SA_NOCLDSTOP: ::c_int = 0x0008; +pub const SA_NODEFER: ::c_int = 0x0010; +pub const SA_NOCLDWAIT: ::c_int = 0x0020; +pub const SIGCHLD: ::c_int = 20; pub const SIGBUS: ::c_int = 10; pub const SIG_SETMASK: ::c_int = 3; pub const IPV6_MULTICAST_LOOP: ::c_int = 11; pub const IPV6_V6ONLY: ::c_int = 27; +pub const FD_SETSIZE: usize = 1024; + +f! { + pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + (*set).fds_bits[fd / 32] &= !(1 << (fd % 32)); + return + } + + pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool { + let fd = fd as usize; + return ((*set).fds_bits[fd / 32] & (1 << (fd % 32))) != 0 + } + + pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + (*set).fds_bits[fd / 32] |= 1 << (fd % 32); + return + } + + pub fn FD_ZERO(set: *mut fd_set) -> () { + for slot in (*set).fds_bits.iter_mut() { + *slot = 0; + } + } + + pub fn WIFEXITED(status: ::c_int) -> bool { + (status & 0x7f) == 0 + } + + pub fn WEXITSTATUS(status: ::c_int) -> ::c_int { + status >> 8 + } + + pub fn WTERMSIG(status: ::c_int) -> ::c_int { + status & 0o177 + } +} + extern { pub fn mincore(addr: *const ::c_void, len: ::size_t, vec: *mut c_char) -> ::c_int; diff --git a/src/unix/mod.rs b/src/unix/mod.rs index c78058674d..f29596e3ce 100644 --- a/src/unix/mod.rs +++ b/src/unix/mod.rs @@ -505,6 +505,25 @@ extern { align: ::size_t, size: ::size_t) -> ::c_int; pub fn sigemptyset(set: *mut sigset_t) -> ::c_int; + #[cfg_attr(all(target_os = "macos", target_arch = "x86_64"), + link_name = "select$1050")] + #[cfg_attr(all(target_os = "macos", target_arch = "x86"), + link_name = "select$UNIX2003")] + pub fn select(nfds: ::c_int, + readfs: *mut fd_set, + writefds: *mut fd_set, + errorfds: *mut fd_set, + timeout: *mut timeval) -> ::c_int; + #[cfg_attr(all(target_os = "macos", target_arch = "x86_64"), + link_name = "pselect$1050")] + #[cfg_attr(all(target_os = "macos", target_arch = "x86"), + link_name = "pselect$UNIX2003")] + pub fn pselect(nfds: ::c_int, + readfs: *mut fd_set, + writefds: *mut fd_set, + errorfds: *mut fd_set, + timeout: *const timespec, + sigmask: *const sigset_t) -> ::c_int; } cfg_if! { diff --git a/src/unix/notbsd/android/mod.rs b/src/unix/notbsd/android/mod.rs index e26bceac30..ee2765a3be 100644 --- a/src/unix/notbsd/android/mod.rs +++ b/src/unix/notbsd/android/mod.rs @@ -179,7 +179,9 @@ pub const FIOCLEX: ::c_ulong = 0x5451; pub const SA_ONSTACK: ::c_ulong = 0x08000000; pub const SA_SIGINFO: ::c_ulong = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; +pub const SIGCHLD: ::c_int = 17; pub const SIGBUS: ::c_int = 7; pub const SIG_SETMASK: ::c_int = 2; diff --git a/src/unix/notbsd/linux/mips.rs b/src/unix/notbsd/linux/mips.rs index 607e6a14c4..ea9947cdf5 100644 --- a/src/unix/notbsd/linux/mips.rs +++ b/src/unix/notbsd/linux/mips.rs @@ -202,11 +202,13 @@ pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 32; pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4; pub const FIOCLEX: ::c_ulong = 0x6601; -pub const FIONBIO: ::c_int = 0x667e; +pub const FIONBIO: ::c_ulong = 0x667e; pub const SA_ONSTACK: ::c_ulong = 0x08000000; pub const SA_SIGINFO: ::c_ulong = 0x00000008; +pub const SA_NOCLDWAIT: ::c_int = 0x00010000; +pub const SIGCHLD: ::c_int = 18; pub const SIGBUS: ::c_int = 10; pub const SIG_SETMASK: ::c_int = 3; diff --git a/src/unix/notbsd/linux/notmips/mod.rs b/src/unix/notbsd/linux/notmips/mod.rs index f69b1ac7f0..1b01327d7b 100644 --- a/src/unix/notbsd/linux/notmips/mod.rs +++ b/src/unix/notbsd/linux/notmips/mod.rs @@ -167,11 +167,13 @@ pub const TCP_TIMESTAMP: ::c_int = 24; pub const SO_REUSEPORT: ::c_int = 15; pub const FIOCLEX: ::c_ulong = 0x5451; -pub const FIONBIO: ::c_int = 0x5421; +pub const FIONBIO: ::c_ulong = 0x5421; pub const SA_ONSTACK: ::c_ulong = 0x08000000; pub const SA_SIGINFO: ::c_ulong = 0x00000004; +pub const SA_NOCLDWAIT: ::c_int = 0x00000002; +pub const SIGCHLD: ::c_int = 17; pub const SIGBUS: ::c_int = 7; pub const SIG_SETMASK: ::c_int = 2; diff --git a/src/unix/notbsd/mod.rs b/src/unix/notbsd/mod.rs index cd7547ccef..2cc900e0e2 100644 --- a/src/unix/notbsd/mod.rs +++ b/src/unix/notbsd/mod.rs @@ -1,3 +1,5 @@ +use dox::mem; + pub type rlim_t = c_ulong; pub type sa_family_t = u16; pub type pthread_key_t = ::c_uint; @@ -66,8 +68,18 @@ s! { pub sll_halen: ::c_uchar, pub sll_addr: [::c_uchar; 8] } + + pub struct fd_set { + fds_bits: [::c_ulong; FD_SETSIZE / ULONG_SIZE], + } } +// intentionally not public, only used for fd_set +#[cfg(target_pointer_width = "32")] +const ULONG_SIZE: usize = 32; +#[cfg(target_pointer_width = "64")] +const ULONG_SIZE: usize = 64; + pub const EXIT_FAILURE: ::c_int = 1; pub const EXIT_SUCCESS: ::c_int = 0; pub const RAND_MAX: ::c_int = 2147483647; @@ -287,6 +299,53 @@ pub const LOCK_UN: ::c_int = 8; pub const SIGSTKSZ: ::size_t = 8192; +pub const SA_NODEFER: ::c_int = 0x40000000; +pub const SA_RESETHAND: ::c_int = 0x80000000; +pub const SA_RESTART: ::c_int = 0x10000000; +pub const SA_NOCLDSTOP: ::c_int = 0x00000001; + +pub const FD_SETSIZE: usize = 1024; + +f! { + pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = mem::size_of_val(&(*set).fds_bits[0]); + (*set).fds_bits[fd / size] &= !(1 << (fd % size)); + return + } + + pub fn FD_ISSET(fd: ::c_int, set: *mut fd_set) -> bool { + let fd = fd as usize; + let size = mem::size_of_val(&(*set).fds_bits[0]); + return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0 + } + + pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () { + let fd = fd as usize; + let size = mem::size_of_val(&(*set).fds_bits[0]); + (*set).fds_bits[fd / size] |= 1 << (fd % size); + return + } + + pub fn FD_ZERO(set: *mut fd_set) -> () { + for slot in (*set).fds_bits.iter_mut() { + *slot = 0; + } + } + + pub fn WIFEXITED(status: ::c_int) -> bool { + (status & 0xff) == 0 + } + + pub fn WEXITSTATUS(status: ::c_int) -> ::c_int { + (status >> 8) & 0xff + } + + pub fn WTERMSIG(status: ::c_int) -> ::c_int { + status & 0x7f + } +} + extern { pub fn fdatasync(fd: ::c_int) -> ::c_int; pub fn mincore(addr: *mut ::c_void, len: ::size_t, -- cgit v1.2.1