From f15d5fa9c82a59d6134ca706b047a6baa2c24e58 Mon Sep 17 00:00:00 2001 From: Thomas Orozco Date: Fri, 10 Mar 2023 05:47:27 -0800 Subject: [PATCH] default FDs to CLOEXEC Note: this is a behavior change. Currently, this crate opens FDs without CLOEXEC, which means they persist across exec. This is not the convention throughout the Rust ecosystem, which is to do the opposite: https://github.com/rust-lang/rust/issues/24237 This patch setting CLOEXEC :) Note that doing that after-the-fact on the resulting FD isn't quite good enough: if your process is forking a lot, that's racy. --- perf-event/src/lib.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/perf-event/src/lib.rs b/perf-event/src/lib.rs index 6cb7983..013329e 100644 --- a/perf-event/src/lib.rs +++ b/perf-event/src/lib.rs @@ -205,6 +205,7 @@ pub struct Builder<'a> { who: EventPid<'a>, cpu: Option, group: Option<&'a mut Group>, + cloexec: bool, } #[derive(Debug)] @@ -470,6 +471,7 @@ impl<'a> Default for Builder<'a> { who: EventPid::ThisProcess, cpu: None, group: None, + cloexec: true, } } } @@ -618,6 +620,12 @@ impl<'a> Builder<'a> { self } + /// By default, perf event FDs are open with PERF_FLAG_FD_CLOEXEC, so the FD you get back has + /// CLOEXEC set. Call this to not do so. + pub fn unset_cloexec(mut self) { + self.cloexec = false; + } + /// Place the counter in the given [`Group`]. Groups allow a set of counters /// to be enabled, disabled, or read as a single atomic operation, so that /// the counts can be usefully compared. @@ -656,7 +664,7 @@ impl<'a> Builder<'a> { Some(cpu) => cpu as c_int, None => -1, }; - let (pid, flags) = self.who.as_args(); + let (pid, mut flags) = self.who.as_args(); let group_fd = match self.group { Some(ref mut g) => { g.max_members += 1; @@ -665,6 +673,10 @@ impl<'a> Builder<'a> { None => -1, }; + if self.cloexec { + flags |= perf_event_open_sys::bindings::PERF_FLAG_FD_CLOEXEC; + } + let file = unsafe { File::from_raw_fd(check_errno_syscall(|| { sys::perf_event_open(&mut self.attrs, pid, cpu, group_fd, flags as c_ulong)