@@ -132,11 +132,18 @@ func spawnExecutable(
132
132
#if SWT_TARGET_OS_APPLE
133
133
_ = posix_spawn_file_actions_addinherit_np ( fileActions, fd)
134
134
#else
135
+ // posix_spawn_file_actions_adddup2() will automatically clear
136
+ // FD_CLOEXEC after forking but before execing even if the old and
137
+ // new file descriptors are equal. This behavior is supported by
138
+ // Glibc ≥ 2.29, FreeBSD, OpenBSD, Android (Bionic) and is
139
+ // standardized in POSIX.1-2024 (see https://pubs.opengroup.org/onlinepubs/9799919799/
140
+ // and https://www.austingroupbugs.net/view.php?id=411).
135
141
_ = posix_spawn_file_actions_adddup2 ( fileActions, fd, fd)
136
142
#if canImport(Glibc)
137
- if glibcVersion. major < 2 || ( glibcVersion. major == 2 && glibcVersion. minor < 29 ) {
143
+ if _slowPath ( glibcVersion. major < 2 || ( glibcVersion. major == 2 && glibcVersion. minor < 29 ) ) {
138
144
// This system is using an older version of glibc that does not
139
- // implement FD_CLOEXEC clearing in posix_spawn_file_actions_adddup2().
145
+ // implement FD_CLOEXEC clearing in posix_spawn_file_actions_adddup2(),
146
+ // so we must clear it here in the parent process.
140
147
try setFD_CLOEXEC ( false , onFileDescriptor: fd)
141
148
}
142
149
#endif
@@ -168,8 +175,6 @@ func spawnExecutable(
168
175
#if !SWT_NO_DYNAMIC_LINKING
169
176
// This platform doesn't have POSIX_SPAWN_CLOEXEC_DEFAULT, but we can at
170
177
// least close all file descriptors higher than the highest inherited one.
171
- // We are assuming here that the caller didn't set FD_CLOEXEC on any of
172
- // these file descriptors.
173
178
_ = _posix_spawn_file_actions_addclosefrom_np ? ( fileActions, highestFD + 1 )
174
179
#endif
175
180
#elseif os(FreeBSD)
0 commit comments