lloda pushed a commit to branch main in repository guile. commit 37b4f7146c1a93b38fb3a3945d74ba6f4f6b81ce Author: Olivier Dion <olivier.dion at> AuthorDate: Tue Sep 9 13:35:00 2025 -0400
tmpfile: preserve O_CLOEXEC so children won't prevent removal Guile duplicates the underlying file descriptor stored in a FILE pointer returned by tmpfile(3). This is done to manage the file descriptor with Guile's ports abstraction instead of using the C FILE pointer abstraction. However, the dup(2) system call does not copy the file descriptor flags (O_CLOEXEC), which is important for respecting the semantic expected from tmpfile(3) in that the temporary file will not leak to child processes. Fix this by using the fcntl(2) system call using the `F_DUPFD_CLOEXEC' command. * libguile/posix.c (scm_tmpfile): Use fcntl(2) instead of dup(2) when not on MINGW32 systems. [r...@defaultvalue.org: adjust commit summary and tmpfile comment; add NEWS] --- NEWS | 1 + libguile/posix.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index d57c342a0..4e7701ca1 100644 --- a/NEWS +++ b/NEWS @@ -209,6 +209,7 @@ change. Previously they could if given the standard-vtable-fields, but inital values that weren't compatible with a vtable. (<https://bugs.gnu.org/78789>) +** 'tmpfile' preserves O_CLOEXEC so children won't prevent removal on exit Changes in 3.0.10 (since 3.0.9) diff --git a/libguile/posix.c b/libguile/posix.c index c8bbb0f83..9add4bb02 100644 --- a/libguile/posix.c +++ b/libguile/posix.c @@ -1825,7 +1825,10 @@ SCM_DEFINE (scm_tmpfile, "tmpfile", 0, 0, 0, SCM_SYSERROR; #ifndef __MINGW32__ - fd = dup (fileno (rv)); + /* Use F_DUPFD_CLOEXEC to preserve the tmpfile descriptor's O_CLOEXEC + flag so that children can't prevent the file from being removed + when this process terminates. */ + fd = fcntl (fileno (rv), F_DUPFD_CLOEXEC, 0); fclose (rv); #else fd = fileno (rv);