From 30b81469f1502cde2d8e999cca30b217a5f9cd8a Mon Sep 17 00:00:00 2001 From: yukang Date: Fri, 17 Oct 2025 11:52:32 +0800 Subject: [PATCH] Update comments in do_exec and add assertion for fd flag --- library/std/src/sys/process/unix/common.rs | 5 +++-- library/std/src/sys/process/unix/unix.rs | 10 +++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/library/std/src/sys/process/unix/common.rs b/library/std/src/sys/process/unix/common.rs index 1d5909e99bacc..5a61ab319950b 100644 --- a/library/std/src/sys/process/unix/common.rs +++ b/library/std/src/sys/process/unix/common.rs @@ -105,8 +105,9 @@ pub struct Command { setsid: bool, } -// passed to do_exec() with configuration of what the child stdio should look -// like +// passed to do_exec() with configuration of what the child stdio should look like. +// SAFETY: don't add any fields here that would require allocation or freeing, +// because of the safety requirements of do_exec(). #[cfg_attr(target_os = "vita", allow(dead_code))] pub struct ChildPipes { pub stdin: ChildStdio, diff --git a/library/std/src/sys/process/unix/unix.rs b/library/std/src/sys/process/unix/unix.rs index 7d944f2f7eef1..59695921065a1 100644 --- a/library/std/src/sys/process/unix/unix.rs +++ b/library/std/src/sys/process/unix/unix.rs @@ -268,12 +268,9 @@ impl Command { // // For this reason, the block of code below should contain 0 // invocations of either malloc of free (or their related friends). + // ChildPipes does not involve any memory allocation or freeing. // - // As an example of not having malloc/free traffic, we don't close - // this file descriptor by dropping the FileDesc (which contains an - // allocation). Instead we just close it manually. This will never - // have the drop glue anyway because this code never returns (the - // child will either exec() or invoke libc::exit) + // The FileDesc will be closed because of FD_CLOEXEC flag is set. #[cfg(not(any(target_os = "tvos", target_os = "watchos")))] unsafe fn do_exec( &mut self, @@ -283,12 +280,15 @@ impl Command { use crate::sys::{self, cvt_r}; if let Some(fd) = stdio.stdin.fd() { + debug_assert!((libc::fcntl(fd, libc::F_GETFD) & libc::FD_CLOEXEC) != 0); cvt_r(|| libc::dup2(fd, libc::STDIN_FILENO))?; } if let Some(fd) = stdio.stdout.fd() { + debug_assert!((libc::fcntl(fd, libc::F_GETFD) & libc::FD_CLOEXEC) != 0); cvt_r(|| libc::dup2(fd, libc::STDOUT_FILENO))?; } if let Some(fd) = stdio.stderr.fd() { + debug_assert!((libc::fcntl(fd, libc::F_GETFD) & libc::FD_CLOEXEC) != 0); cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO))?; }