Skip to content

Commit e95927c

Browse files
weissiJohannes Weiss
authored andcommitted
do not inherit fds
(cherry picked from commit f4eb86b) (cherry picked from commit 7022366)
1 parent 914a8ae commit e95927c

File tree

3 files changed

+52
-1
lines changed

3 files changed

+52
-1
lines changed

Foundation/Process.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
//
99

1010
import CoreFoundation
11+
import Darwin
1112

1213
extension Process {
1314
public enum TerminationReason : Int {
@@ -872,6 +873,16 @@ open class Process: NSObject {
872873
posix(_CFPosixSpawnFileActionsAddClose(fileActions, fd))
873874
}
874875

876+
#if os(macOS)
877+
var spawnAttrs: posix_spawnattr_t? = nil
878+
posix_spawnattr_init(&spawnAttrs)
879+
posix_spawnattr_setflags(&spawnAttrs, .init(POSIX_SPAWN_CLOEXEC_DEFAULT))
880+
#else
881+
for fd in 3..<getdtablesize() {
882+
posix(_CFPosixSpawnFileActionsAddClose(fileActions, fd))
883+
}
884+
#endif
885+
875886
let fileManager = FileManager()
876887
let previousDirectoryPath = fileManager.currentDirectoryPath
877888
if let dir = currentDirectoryURL?.path, !fileManager.changeCurrentDirectoryPath(dir) {
@@ -885,9 +896,16 @@ open class Process: NSObject {
885896

886897
// Launch
887898
var pid = pid_t()
899+
#if os(macOS)
900+
guard _CFPosixSpawn(&pid, launchPath, fileActions, &spawnAttrs, argv, envp) == 0 else {
901+
throw _NSErrorWithErrno(errno, reading: true, path: launchPath)
902+
}
903+
#else
888904
guard _CFPosixSpawn(&pid, launchPath, fileActions, nil, argv, envp) == 0 else {
889905
throw _NSErrorWithErrno(errno, reading: true, path: launchPath)
890906
}
907+
#endif
908+
891909

892910
// Close the write end of the input and output pipes.
893911
if let pipe = standardInput as? Pipe {

TestFoundation/TestProcess.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,26 @@ class TestProcess : XCTestCase {
750750
}
751751
}
752752

753+
func test_fileDescriptorsAreNotInherited() throws {
754+
let task = Process()
755+
let clonedFD = dup(1)
756+
task.executableURL = xdgTestHelperURL()
757+
task.arguments = ["--print-open-file-descriptors"]
758+
task.standardInput = FileHandle.nullDevice
759+
let stdoutPipe = Pipe()
760+
task.standardOutput = stdoutPipe.fileHandleForWriting
761+
task.standardError = FileHandle.nullDevice
762+
XCTAssertNoThrow(try task.run())
763+
764+
try task.run()
765+
try stdoutPipe.fileHandleForWriting.close()
766+
let stdoutData = try stdoutPipe.fileHandleForReading.readToEnd()
767+
task.waitUntilExit()
768+
print(String(decoding: stdoutData ?? Data(), as: Unicode.UTF8.self))
769+
XCTAssertEqual("0\n1\n2\n", String(decoding: stdoutData ?? Data(), as: Unicode.UTF8.self))
770+
close(clonedFD)
771+
}
772+
753773
static var allTests: [(String, (TestProcess) -> () throws -> Void)] {
754774
var tests = [
755775
("test_exit0" , test_exit0),
@@ -779,6 +799,7 @@ class TestProcess : XCTestCase {
779799
("test_currentDirectory", test_currentDirectory),
780800
("test_pipeCloseBeforeLaunch", test_pipeCloseBeforeLaunch),
781801
("test_multiProcesses", test_multiProcesses),
802+
("test_fileDescriptorsAreNotInherited", test_fileDescriptorsAreNotInherited),
782803
]
783804

784805
#if !os(Windows)

TestFoundation/xdgTestHelper/main.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,15 @@ func cat(_ args: ArraySlice<String>.Iterator) {
196196
exit(exitCode)
197197
}
198198

199+
func printOpenFileDescriptors() {
200+
for fd in 0..<getdtablesize() {
201+
if fcntl(fd, F_GETFD) != -1 {
202+
print(fd)
203+
}
204+
}
205+
exit(0)
206+
}
207+
199208
// -----
200209

201210
var arguments = ProcessInfo.processInfo.arguments.dropFirst().makeIterator()
@@ -255,7 +264,10 @@ case "--nspathfor":
255264
case "--signal-test":
256265
signalTest()
257266
#endif
258-
267+
268+
case "--print-open-file-descriptors":
269+
printOpenFileDescriptors()
270+
259271
default:
260272
fatalError("These arguments are not recognized. Only run this from a unit test.")
261273
}

0 commit comments

Comments
 (0)