Skip to content

Commit e243312

Browse files
authored
Merge pull request #110 from Carthage/nsconcretetask-setstartsnewprocessgroup
Use the `NSConcreteTask.setStartsNewProcessGroup` private API to terminate subprocesses when the parent process exits
2 parents 8420220 + 9143189 commit e243312

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

Sources/Task.swift

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -390,10 +390,13 @@ extension Task {
390390
/// - Parameters:
391391
/// - standardInput: Data to stream to standard input of the launched process. If nil, stdin will
392392
/// be inherited from the parent process.
393+
/// - shouldBeTerminatedOnParentExit: A flag to control whether the launched child process should be terminated
394+
/// when the parent process exits. The default value is `false`.
393395
///
394396
/// - Returns: A producer that will launch the receiver when started, then send
395397
/// `TaskEvent`s as execution proceeds.
396-
public func launch(standardInput: SignalProducer<Data, NoError>? = nil) -> SignalProducer<TaskEvent<Data>, TaskError> {
398+
public func launch(standardInput: SignalProducer<Data, NoError>? = nil,
399+
shouldBeTerminatedOnParentExit: Bool = false) -> SignalProducer<TaskEvent<Data>, TaskError> {
397400
return SignalProducer { observer, lifetime in
398401
let queue = DispatchQueue(label: self.description, attributes: [])
399402
let group = Task.group
@@ -402,6 +405,15 @@ extension Task {
402405
process.launchPath = self.launchPath
403406
process.arguments = self.arguments
404407

408+
if shouldBeTerminatedOnParentExit {
409+
// This is for terminating subprocesses when the parent process exits.
410+
// See https://github.com/Carthage/ReactiveTask/issues/3 for the details.
411+
let selector = Selector(("setStartsNewProcessGroup:"))
412+
if process.responds(to: selector) {
413+
process.perform(selector, with: false as NSNumber)
414+
}
415+
}
416+
405417
if let cwd = self.workingDirectoryPath {
406418
process.currentDirectoryPath = cwd
407419
}
@@ -484,8 +496,8 @@ extension Task {
484496
process.standardError = stderrPipe.writeHandle
485497

486498
group.enter()
487-
process.terminationHandler = { nstask in
488-
let terminationStatus = nstask.terminationStatus
499+
process.terminationHandler = { process in
500+
let terminationStatus = process.terminationStatus
489501
if terminationStatus == EXIT_SUCCESS {
490502
// Wait for stderr to finish, then pass
491503
// through stdout.

0 commit comments

Comments
 (0)