Skip to content

Commit 8b849ef

Browse files
authored
Add CLOEXEC flags (#403)
* fix(driver): set cloexec for socket * fix(driver): set cloexec for file
1 parent 6df02c8 commit 8b849ef

File tree

3 files changed

+118
-73
lines changed

3 files changed

+118
-73
lines changed

compio-driver/src/iour/op.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ impl<
4545
impl OpCode for OpenFile {
4646
fn create_entry(self: Pin<&mut Self>) -> OpEntry {
4747
opcode::OpenAt::new(Fd(libc::AT_FDCWD), self.path.as_ptr())
48-
.flags(self.flags)
48+
.flags(self.flags | libc::O_CLOEXEC)
4949
.mode(self.mode)
5050
.build()
5151
.into()
@@ -262,9 +262,13 @@ impl OpCode for HardLink {
262262

263263
impl OpCode for CreateSocket {
264264
fn create_entry(self: Pin<&mut Self>) -> OpEntry {
265-
opcode::Socket::new(self.domain, self.socket_type, self.protocol)
266-
.build()
267-
.into()
265+
opcode::Socket::new(
266+
self.domain,
267+
self.socket_type | libc::SOCK_CLOEXEC,
268+
self.protocol,
269+
)
270+
.build()
271+
.into()
268272
}
269273

270274
fn call_blocking(self: Pin<&mut Self>) -> io::Result<usize> {
@@ -294,6 +298,7 @@ impl<S: AsRawFd> OpCode for Accept<S> {
294298
&mut this.buffer as *mut sockaddr_storage as *mut libc::sockaddr,
295299
&mut this.addr_len,
296300
)
301+
.flags(libc::SOCK_CLOEXEC)
297302
.build()
298303
.into()
299304
}

compio-driver/src/poll/op.rs

+108-11
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::{
44
ffi::CString,
55
io,
66
marker::PhantomPinned,
7-
os::fd::{FromRawFd, OwnedFd},
7+
os::fd::{FromRawFd, IntoRawFd, OwnedFd},
88
pin::Pin,
99
task::Poll,
1010
};
@@ -20,7 +20,7 @@ use libc::open64 as open;
2020
use libc::{pread, preadv, pwrite, pwritev};
2121
#[cfg(any(target_os = "linux", target_os = "android", target_os = "hurd"))]
2222
use libc::{pread64 as pread, preadv64 as preadv, pwrite64 as pwrite, pwritev64 as pwritev};
23-
use socket2::SockAddr;
23+
use socket2::{SockAddr, Socket as Socket2};
2424

2525
use super::{AsRawFd, Decision, OpCode, OpType, sockaddr_storage, socklen_t, syscall};
2626
pub use crate::unix::op::*;
@@ -56,7 +56,7 @@ impl OpCode for OpenFile {
5656
fn operate(self: Pin<&mut Self>) -> Poll<io::Result<usize>> {
5757
Poll::Ready(Ok(syscall!(open(
5858
self.path.as_ptr(),
59-
self.flags,
59+
self.flags | libc::O_CLOEXEC,
6060
self.mode as libc::c_int
6161
))? as _))
6262
}
@@ -467,15 +467,73 @@ impl OpCode for HardLink {
467467
}
468468
}
469469

470+
impl CreateSocket {
471+
unsafe fn call(self: Pin<&mut Self>) -> io::Result<libc::c_int> {
472+
#[allow(unused_mut)]
473+
let mut ty: i32 = self.socket_type;
474+
#[cfg(any(
475+
target_os = "android",
476+
target_os = "dragonfly",
477+
target_os = "freebsd",
478+
target_os = "fuchsia",
479+
target_os = "hurd",
480+
target_os = "illumos",
481+
target_os = "linux",
482+
target_os = "netbsd",
483+
target_os = "openbsd",
484+
target_os = "cygwin",
485+
))]
486+
{
487+
ty |= libc::SOCK_CLOEXEC | libc::SOCK_NONBLOCK;
488+
}
489+
let fd = syscall!(libc::socket(self.domain, ty, self.protocol))?;
490+
let socket = Socket2::from_raw_fd(fd);
491+
#[cfg(not(any(
492+
target_os = "android",
493+
target_os = "dragonfly",
494+
target_os = "freebsd",
495+
target_os = "fuchsia",
496+
target_os = "hurd",
497+
target_os = "illumos",
498+
target_os = "linux",
499+
target_os = "netbsd",
500+
target_os = "openbsd",
501+
target_os = "espidf",
502+
target_os = "vita",
503+
target_os = "cygwin",
504+
)))]
505+
socket.set_cloexec(true)?;
506+
#[cfg(any(
507+
target_os = "ios",
508+
target_os = "macos",
509+
target_os = "tvos",
510+
target_os = "watchos",
511+
))]
512+
socket.set_nosigpipe(true)?;
513+
#[cfg(not(any(
514+
target_os = "android",
515+
target_os = "dragonfly",
516+
target_os = "freebsd",
517+
target_os = "fuchsia",
518+
target_os = "hurd",
519+
target_os = "illumos",
520+
target_os = "linux",
521+
target_os = "netbsd",
522+
target_os = "openbsd",
523+
target_os = "cygwin",
524+
)))]
525+
socket.set_nonblocking(true)?;
526+
Ok(socket.into_raw_fd())
527+
}
528+
}
529+
470530
impl OpCode for CreateSocket {
471531
fn pre_submit(self: Pin<&mut Self>) -> io::Result<Decision> {
472532
Ok(Decision::Blocking)
473533
}
474534

475535
fn operate(self: Pin<&mut Self>) -> Poll<io::Result<usize>> {
476-
Poll::Ready(Ok(
477-
syscall!(libc::socket(self.domain, self.socket_type, self.protocol))? as _,
478-
))
536+
Poll::Ready(Ok(unsafe { self.call()? } as _))
479537
}
480538
}
481539

@@ -504,11 +562,50 @@ impl OpCode for CloseSocket {
504562
impl<S: AsRawFd> Accept<S> {
505563
unsafe fn call(self: Pin<&mut Self>) -> libc::c_int {
506564
let this = self.get_unchecked_mut();
507-
libc::accept(
508-
this.fd.as_raw_fd(),
509-
&mut this.buffer as *mut _ as *mut _,
510-
&mut this.addr_len,
511-
)
565+
#[cfg(any(
566+
target_os = "android",
567+
target_os = "dragonfly",
568+
target_os = "freebsd",
569+
target_os = "fuchsia",
570+
target_os = "illumos",
571+
target_os = "linux",
572+
target_os = "netbsd",
573+
target_os = "openbsd",
574+
target_os = "cygwin",
575+
))]
576+
{
577+
libc::accept4(
578+
this.fd.as_raw_fd(),
579+
&mut this.buffer as *mut _ as *mut _,
580+
&mut this.addr_len,
581+
libc::SOCK_NONBLOCK | libc::SOCK_CLOEXEC,
582+
)
583+
}
584+
#[cfg(not(any(
585+
target_os = "android",
586+
target_os = "dragonfly",
587+
target_os = "freebsd",
588+
target_os = "fuchsia",
589+
target_os = "illumos",
590+
target_os = "linux",
591+
target_os = "netbsd",
592+
target_os = "openbsd",
593+
target_os = "cygwin",
594+
)))]
595+
{
596+
|| -> io::Result<libc::c_int> {
597+
let fd = syscall!(libc::accept(
598+
this.fd.as_raw_fd(),
599+
&mut this.buffer as *mut _ as *mut _,
600+
&mut this.addr_len,
601+
))?;
602+
let socket = Socket2::from_raw_fd(fd);
603+
socket.set_cloexec(true)?;
604+
socket.set_nonblocking(true)?;
605+
Ok(socket.into_raw_fd())
606+
}()
607+
.unwrap_or(-1)
608+
}
512609
}
513610
}
514611

compio-net/src/socket.rs

+1-58
Original file line numberDiff line numberDiff line change
@@ -28,41 +28,6 @@ pub struct Socket {
2828

2929
impl Socket {
3030
pub fn from_socket2(socket: Socket2) -> io::Result<Self> {
31-
#[cfg(unix)]
32-
{
33-
#[cfg(not(any(
34-
target_os = "android",
35-
target_os = "dragonfly",
36-
target_os = "freebsd",
37-
target_os = "fuchsia",
38-
target_os = "hurd",
39-
target_os = "illumos",
40-
target_os = "linux",
41-
target_os = "netbsd",
42-
target_os = "openbsd",
43-
target_os = "espidf",
44-
target_os = "vita",
45-
)))]
46-
socket.set_cloexec(true)?;
47-
#[cfg(any(
48-
target_os = "ios",
49-
target_os = "macos",
50-
target_os = "tvos",
51-
target_os = "watchos",
52-
))]
53-
socket.set_nosigpipe(true)?;
54-
// On Linux we use blocking socket
55-
// Newer kernels have the patch that allows to arm io_uring poll mechanism for
56-
// non blocking socket when there is no connections in listen queue
57-
//
58-
// https://patchwork.kernel.org/project/linux-block/patch/[email protected]/#22949861
59-
if cfg!(not(all(target_os = "linux", feature = "io-uring")))
60-
|| compio_driver::DriverType::is_polling()
61-
{
62-
socket.set_nonblocking(true)?;
63-
}
64-
}
65-
6631
Ok(Self {
6732
socket: Attacher::new(socket)?,
6833
})
@@ -98,26 +63,9 @@ impl Socket {
9863
pub async fn new(domain: Domain, ty: Type, protocol: Option<Protocol>) -> io::Result<Self> {
9964
use std::os::fd::FromRawFd;
10065

101-
#[allow(unused_mut)]
102-
let mut ty: i32 = ty.into();
103-
#[cfg(any(
104-
target_os = "android",
105-
target_os = "dragonfly",
106-
target_os = "freebsd",
107-
target_os = "fuchsia",
108-
target_os = "hurd",
109-
target_os = "illumos",
110-
target_os = "linux",
111-
target_os = "netbsd",
112-
target_os = "openbsd",
113-
))]
114-
{
115-
ty |= libc::SOCK_CLOEXEC;
116-
}
117-
11866
let op = CreateSocket::new(
11967
domain.into(),
120-
ty,
68+
ty.into(),
12169
protocol.map(|p| p.into()).unwrap_or_default(),
12270
);
12371
let BufResult(res, _) = compio_runtime::submit(op).await;
@@ -163,11 +111,6 @@ impl Socket {
163111
let BufResult(res, op) = compio_runtime::submit(op).await;
164112
let addr = op.into_addr();
165113
let accept_sock = unsafe { Socket2::from_raw_fd(res? as _) };
166-
if cfg!(not(all(target_os = "linux", feature = "io-uring")))
167-
|| compio_driver::DriverType::is_polling()
168-
{
169-
accept_sock.set_nonblocking(true)?;
170-
}
171114
let accept_sock = Self::from_socket2(accept_sock)?;
172115
Ok((accept_sock, addr))
173116
}

0 commit comments

Comments
 (0)