diff --git a/src/sys/unix/selector/epoll.rs b/src/sys/unix/selector/epoll.rs index 929e223ba..38667d66c 100644 --- a/src/sys/unix/selector/epoll.rs +++ b/src/sys/unix/selector/epoll.rs @@ -41,7 +41,7 @@ impl Selector { } pub fn try_clone(&self) -> io::Result { - syscall!(fcntl(self.ep, libc::F_DUPFD_CLOEXEC, 0)).map(|ep| Selector { + syscall!(fcntl(self.ep, libc::F_DUPFD_CLOEXEC, super::LOWEST_FD)).map(|ep| Selector { // It's the same selector, so we use the same id. #[cfg(debug_assertions)] id: self.id, diff --git a/src/sys/unix/selector/kqueue.rs b/src/sys/unix/selector/kqueue.rs index 34f534028..b36a5375e 100644 --- a/src/sys/unix/selector/kqueue.rs +++ b/src/sys/unix/selector/kqueue.rs @@ -87,7 +87,7 @@ impl Selector { } pub fn try_clone(&self) -> io::Result { - syscall!(dup(self.kq)).map(|kq| Selector { + syscall!(fcntl(self.kq, libc::F_DUPFD_CLOEXEC, super::LOWEST_FD)).map(|kq| Selector { // It's the same selector, so we use the same id. #[cfg(debug_assertions)] id: self.id, diff --git a/src/sys/unix/selector/mod.rs b/src/sys/unix/selector/mod.rs index 752589817..b73d645bd 100644 --- a/src/sys/unix/selector/mod.rs +++ b/src/sys/unix/selector/mod.rs @@ -33,3 +33,13 @@ mod kqueue; target_os = "openbsd" ))] pub(crate) use self::kqueue::{event, Event, Events, Selector}; + +/// Lowest file descriptor used in `Selector::try_clone`. +/// +/// # Notes +/// +/// Usually fds 0, 1 and 2 are standard in, out and error. Some application +/// blindly assume this to be true, which means using any one of those a select +/// could result in some interesting and unexpected errors. Avoid that by using +/// an fd that doesn't have a pre-determined usage. +const LOWEST_FD: libc::c_int = 3;