Skip to content

Commit

Permalink
Set the CLOEXEC flag for file descriptors created
Browse files Browse the repository at this point in the history
  • Loading branch information
alexcrichton authored and carllerche committed Aug 26, 2016
1 parent 6ce2490 commit ce5d4fb
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 3 deletions.
35 changes: 33 additions & 2 deletions src/sys/unix/epoll.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
use {convert, io, Ready, PollOpt, Token};
use event::Event;
use nix::sys::epoll::*;
use libc::{c_int, c_void};
use libc;
use nix::sys::epoll::{EPOLLERR, EPOLLHUP, EPOLLRDHUP, EPOLLONESHOT};
use nix::sys::epoll::{EPOLLET, EPOLLOUT, EpollEvent, EPOLLIN, EPOLLPRI};
use nix::sys::epoll::{EpollEventKind, epoll_ctl, EpollOp, epoll_wait};
use nix::unistd::close;
use std::mem;
use std::os::unix::io::RawFd;
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
use std::time::Duration;
Expand All @@ -19,11 +24,37 @@ pub struct Selector {
epfd: RawFd
}

// Emulate `epoll_create` by using `epoll_create1` if it's available and
// otherwise falling back to `epoll_create` followed by a call to set the
// CLOEXEC flag.
unsafe fn epoll_create() -> io::Result<RawFd> {
let name = "epoll_create1\0".as_ptr();
let ptr = libc::dlsym(libc::RTLD_DEFAULT, name as *const _);
let fd;
if ptr.is_null() {
fd = libc::epoll_create(1024);
if fd > 0 {
libc::ioctl(fd, libc::FIOCLEX);
}
} else {
type EpollCreate1 = unsafe extern fn(c_int) -> c_int;
let epoll_create1 = mem::transmute::<*mut c_void, EpollCreate1>(ptr);
fd = epoll_create1(libc::EPOLL_CLOEXEC);
}
if fd >= 0 {
Ok(fd)
} else {
Err(io::Error::last_os_error())

}
}

impl Selector {
pub fn new() -> io::Result<Selector> {
let epfd = try!(unsafe { epoll_create() });

// offset by 1 to avoid choosing 0 as the id of a selector
let id = NEXT_ID.fetch_add(1, Ordering::Relaxed) + 1;
let epfd = try!(epoll_create().map_err(super::from_nix_error));

Ok(Selector {
id: id,
Expand Down
6 changes: 5 additions & 1 deletion src/sys/unix/kqueue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use nix::libc::timespec;
use nix::unistd::close;
use nix::sys::event::{EventFilter, EventFlag, FilterFlag, KEvent, kqueue, kevent, kevent_ts};
use nix::sys::event::{EV_ADD, EV_CLEAR, EV_DELETE, EV_DISABLE, EV_ENABLE, EV_EOF, EV_ERROR, EV_ONESHOT};
use libc::time_t;
use libc::{self, time_t};
use std::{cmp, fmt, slice};
use std::cell::UnsafeCell;
use std::os::unix::io::RawFd;
Expand Down Expand Up @@ -37,6 +37,10 @@ impl Selector {
let id = NEXT_ID.fetch_add(1, Ordering::Relaxed) + 1;
let kq = try!(kqueue().map_err(super::from_nix_error));

unsafe {
libc::ioctl(kq, libc::FIOCLEX);
}

Ok(Selector {
id: id,
kq: kq,
Expand Down

0 comments on commit ce5d4fb

Please sign in to comment.