Skip to content

Commit cfeed11

Browse files
committed
Tweaks + fix accept4
1 parent 74d49ab commit cfeed11

File tree

7 files changed

+104
-15
lines changed

7 files changed

+104
-15
lines changed

src/fcntl.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ mod ffi {
1616
mod os {
1717
use libc::{c_int, c_short, off_t, pid_t};
1818

19+
#[repr(C)]
1920
pub struct flock {
2021
pub l_type: c_short,
2122
pub l_whence: c_short,
@@ -43,6 +44,7 @@ mod ffi {
4344
mod os {
4445
use libc::{c_int, c_short, off_t, pid_t};
4546

47+
#[repr(C)]
4648
pub struct flock {
4749
pub l_start: off_t,
4850
pub l_len: off_t,

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![crate_name = "nix"]
22
#![feature(globs)]
3+
#![feature(linkage)]
34
#![allow(non_camel_case_types)]
45

56
extern crate libc;

src/sched.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub type CloneCb<'a> = ||:'a -> int;
3434
mod ffi {
3535
use libc::{c_void, c_int};
3636

37-
type CloneCb = extern fn (data: *const super::CloneCb) -> c_int;
37+
type CloneCb = extern "C" fn (data: *const super::CloneCb) -> c_int;
3838

3939
extern {
4040
// create a child process

src/sys/epoll.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::fmt;
12
use libc::c_int;
23
use fcntl::Fd;
34
use errno::{SysResult, SysError, from_ffi};
@@ -32,13 +33,49 @@ bitflags!(
3233
}
3334
)
3435

36+
impl fmt::Show for EpollEventKind {
37+
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
38+
let variants = [
39+
(EPOLLIN, "EPOLLIN"),
40+
(EPOLLPRI, "EPOLLPRI"),
41+
(EPOLLOUT, "EPOLLOUT"),
42+
(EPOLLRDNORM, "EPOLLRDNORM"),
43+
(EPOLLRDBAND, "EPOLLRDBAND"),
44+
(EPOLLWRNORM, "EPOLLWRNORM"),
45+
(EPOLLWRBAND, "EPOLLWRBAND"),
46+
(EPOLLMSG, "EPOLLMSG"),
47+
(EPOLLERR, "EPOLLERR"),
48+
(EPOLLHUP, "EPOLLHUP"),
49+
(EPOLLRDHUP, "EPOLLRDHUP"),
50+
(EPOLLWAKEUP, "EPOLLWAKEUP"),
51+
(EPOLLONESHOT, "EPOLLONESHOT"),
52+
(EPOLLET, "EPOLLET")];
53+
54+
let mut first = true;
55+
56+
for &(val, name) in variants.iter() {
57+
if self.contains(val) {
58+
if first {
59+
first = false;
60+
try!(write!(fmt, "{}", name));
61+
} else {
62+
try!(write!(fmt, "|{}", name));
63+
}
64+
}
65+
}
66+
67+
Ok(())
68+
}
69+
}
70+
3571
#[repr(C)]
3672
pub enum EpollOp {
3773
EpollCtlAdd = 1,
3874
EpollCtlDel = 2,
3975
EpollCtlMod = 3
4076
}
4177

78+
#[repr(C)]
4279
pub struct EpollEvent {
4380
pub events: EpollEventKind,
4481
pub data: u64

src/sys/event.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use libc::{timespec, time_t, c_int, c_long, c_void};
1+
use libc::{timespec, time_t, c_int, c_long};
22
use errno::{SysResult, SysError};
33
use fcntl::Fd;
44

@@ -8,7 +8,7 @@ mod ffi {
88
pub use libc::{c_int, c_void, uintptr_t, intptr_t, timespec};
99
use super::{EventFilter, EventFlag, FilterFlag};
1010

11-
// Packed to 32 bytes
11+
#[repr(C)]
1212
pub struct kevent {
1313
pub ident: uintptr_t, // 8
1414
pub filter: EventFilter, // 2

src/sys/socket.rs

Lines changed: 60 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,10 @@ pub use libc::{in_addr, sockaddr_in, sockaddr_in6, sockaddr_un, sa_family_t};
99
pub use self::consts::*;
1010

1111
mod ffi {
12-
use libc::{c_int, c_void, sockaddr, socklen_t};
12+
use libc::{c_int, c_void, socklen_t};
1313
pub use libc::{socket, listen, bind, accept, connect, setsockopt};
1414

1515
extern {
16-
pub fn accept4(
17-
sockfd: c_int,
18-
addr: *mut sockaddr,
19-
addrlen: *mut socklen_t,
20-
flags: c_int) -> c_int;
21-
2216
pub fn getsockopt(
2317
sockfd: c_int,
2418
level: c_int,
@@ -169,7 +163,7 @@ mod consts {
169163
}
170164

171165
pub fn socket(domain: AddressFamily, mut ty: SockType, flags: SockFlag) -> SysResult<Fd> {
172-
let feat_atomic = features::atomic_cloexec(); // TODO: detect
166+
let feat_atomic = features::atomic_cloexec();
173167

174168
if feat_atomic {
175169
ty = ty | flags.bits();
@@ -183,8 +177,13 @@ pub fn socket(domain: AddressFamily, mut ty: SockType, flags: SockFlag) -> SysRe
183177
}
184178

185179
if !feat_atomic {
186-
try!(fcntl(res, F_SETFD(FD_CLOEXEC)));
187-
try!(fcntl(res, F_SETFL(O_NONBLOCK)));
180+
if flags.contains(SOCK_CLOEXEC) {
181+
try!(fcntl(res, F_SETFD(FD_CLOEXEC)));
182+
}
183+
184+
if flags.contains(SOCK_NONBLOCK) {
185+
try!(fcntl(res, F_SETFL(O_NONBLOCK)));
186+
}
188187
}
189188

190189
Ok(res)
@@ -217,17 +216,66 @@ pub fn accept(sockfd: Fd) -> SysResult<Fd> {
217216
Ok(res)
218217
}
219218

219+
#[cfg(target_os = "linux")]
220220
pub fn accept4(sockfd: Fd, flags: SockFlag) -> SysResult<Fd> {
221-
// TODO: Check the kernel version
222-
let res = unsafe { ffi::accept4(sockfd, ptr::mut_null(), ptr::mut_null(), flags.bits) };
221+
use libc::sockaddr;
222+
223+
type F = unsafe extern "C" fn(c_int, *mut sockaddr, *mut socklen_t, c_int) -> c_int;
224+
225+
extern {
226+
#[linkage = "extern_weak"]
227+
static accept4: *const ();
228+
}
229+
230+
let feat_atomic = !accept4.is_null();
231+
232+
let res = if feat_atomic {
233+
unsafe {
234+
mem::transmute::<*const (), F>(accept4)(
235+
sockfd, ptr::mut_null(), ptr::mut_null(), flags.bits)
236+
}
237+
} else {
238+
unsafe { ffi::accept(sockfd, ptr::mut_null(), ptr::mut_null()) }
239+
};
240+
241+
if res < 0 {
242+
return Err(SysError::last());
243+
}
244+
245+
if !feat_atomic {
246+
if flags.contains(SOCK_CLOEXEC) {
247+
try!(fcntl(res, F_SETFD(FD_CLOEXEC)));
248+
}
249+
250+
if flags.contains(SOCK_NONBLOCK) {
251+
try!(fcntl(res, F_SETFL(O_NONBLOCK)));
252+
}
253+
}
254+
255+
Ok(res)
256+
}
257+
258+
#[cfg(target_os = "macos")]
259+
#[cfg(target_os = "ios")]
260+
pub fn accept4(sockfd: Fd, flags: SockFlag) -> SysResult<Fd> {
261+
let res = unsafe { ffi::accept(sockfd, ptr::mut_null(), ptr::mut_null()) };
223262

224263
if res < 0 {
225264
return Err(SysError::last());
226265
}
227266

267+
if flags.contains(SOCK_CLOEXEC) {
268+
try!(fcntl(res, F_SETFD(FD_CLOEXEC)));
269+
}
270+
271+
if flags.contains(SOCK_NONBLOCK) {
272+
try!(fcntl(res, F_SETFL(O_NONBLOCK)));
273+
}
274+
228275
Ok(res)
229276
}
230277

278+
231279
pub fn connect(sockfd: Fd, addr: &SockAddr) -> SysResult<()> {
232280
let res = unsafe {
233281
match *addr {

src/sys/utsname.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ mod ffi {
1515
#[cfg(target_arch = "x86_64")]
1616
static UTSNAME_LEN: uint = 65;
1717

18+
#[repr(C)]
1819
pub struct UtsName {
1920
sysname: [c_char, ..UTSNAME_LEN],
2021
nodename: [c_char, ..UTSNAME_LEN],

0 commit comments

Comments
 (0)