summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2023-03-28 23:35:35 +0200
committerLudovic Courtès <ludo@gnu.org>2023-04-02 15:36:25 +0200
commit21ad54b694c676ba608166be137b677bbb747eac (patch)
treecaf82236a4eaf8b45bc41f7965b650f43da8e07c
parente334e59589c3cbfc68d3f7d0d739000e0876b36d (diff)
downloadguile-21ad54b694c676ba608166be137b677bbb747eac.tar.gz
'spawn' closes only open file descriptors on non-GNU/Linux systems.
Fixes <https://bugs.gnu.org/61095>. Reported by Omar Polo <op@omarpolo.com>. * libguile/posix.c (close_inherited_fds_slow): On systems other than GNU/Linux, call 'addclose' only when 'fcntl' succeeds on MAX_FD. * NEWS: Update.
-rw-r--r--NEWS4
-rw-r--r--libguile/posix.c19
2 files changed, 21 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index cad53ea03..ce8d4e120 100644
--- a/NEWS
+++ b/NEWS
@@ -24,7 +24,9 @@ the compiler reports it as "possibly unused".
* Bug fixes
** (ice-9 suspendable-ports) incorrect UTF-8 decoding
- (https://bugs.gnu.org/62290)
+ (<https://bugs.gnu.org/62290>)
+** Fix invalid use of 'posix_spawn' on non-glibc systems
+ (<https://bugs.gnu.org/61095>)
** Hashing of UTF-8 symbols with non-ASCII characters avoids corruption
(<https://bugs.gnu.org/56413>)
diff --git a/libguile/posix.c b/libguile/posix.c
index 3a8be94e4..68e9bfade 100644
--- a/libguile/posix.c
+++ b/libguile/posix.c
@@ -1326,7 +1326,24 @@ static void
close_inherited_fds_slow (posix_spawn_file_actions_t *actions, int max_fd)
{
while (--max_fd > 2)
- posix_spawn_file_actions_addclose (actions, max_fd);
+ {
+ /* Adding a 'close' action for a file descriptor that is not open
+ causes 'posix_spawn' to fail on GNU/Hurd and on OpenBSD, but
+ not on GNU/Linux: <https://bugs.gnu.org/61095>. Hence this
+ strategy:
+
+ - On GNU/Linux, close every FD, since that's the only
+ race-free way to make sure the child doesn't inherit one.
+ - On other systems, only close FDs currently open in the
+ parent; it works, but it's racy (XXX).
+
+ The only reliable option is 'addclosefrom'. */
+#if ! (defined __GLIBC__ && defined __linux__)
+ int flags = fcntl (max_fd, F_GETFD, NULL);
+ if (flags >= 0)
+#endif
+ posix_spawn_file_actions_addclose (actions, max_fd);
+ }
}
static void