Skip to content

Commit 1aaab44

Browse files
committed
Fix a race condition in SystemLogs using an actor for a thread-safe access to process
1 parent 58e0ddd commit 1aaab44

1 file changed

Lines changed: 33 additions & 11 deletions

File tree

Sources/CLI/System/SystemLogs.swift

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,33 @@ extension Application {
3030
abstract: "Fetch system logs for `container` services"
3131
)
3232

33+
private actor ProcessManager {
34+
private let process = Process()
35+
36+
func configure(args: [String]) {
37+
process.launchPath = "/usr/bin/env"
38+
process.arguments = args
39+
process.standardOutput = FileHandle.standardOutput
40+
process.standardError = FileHandle.standardError
41+
}
42+
43+
func run() throws {
44+
try process.run()
45+
}
46+
47+
func waitUntilExit() {
48+
process.waitUntilExit()
49+
}
50+
51+
func terminate() {
52+
process.terminate()
53+
}
54+
55+
var terminationStatus: Int32 {
56+
process.terminationStatus
57+
}
58+
}
59+
3360
@OptionGroup
3461
var global: Flags.Global
3562

@@ -43,12 +70,12 @@ extension Application {
4370
var follow: Bool = false
4471

4572
func run() async throws {
46-
let process = Process()
73+
let processManager = ProcessManager()
4774
let sigHandler = AsyncSignalHandler.create(notify: [SIGINT, SIGTERM])
4875

4976
Task {
5077
for await _ in sigHandler.signals {
51-
process.terminate()
78+
await processManager.terminate()
5279
Darwin.exit(0)
5380
}
5481
}
@@ -62,21 +89,16 @@ extension Application {
6289
}
6390
args.append(contentsOf: ["--predicate", "subsystem = 'com.apple.container'"])
6491

65-
process.launchPath = "/usr/bin/env"
66-
process.arguments = args
67-
68-
process.standardOutput = FileHandle.standardOutput
69-
process.standardError = FileHandle.standardError
70-
71-
try process.run()
72-
process.waitUntilExit()
92+
await processManager.configure(args: args)
93+
try await processManager.run()
94+
await processManager.waitUntilExit()
7395
} catch {
7496
throw ContainerizationError(
7597
.invalidArgument,
7698
message: "failed to system logs: \(error)"
7799
)
78100
}
79-
throw ArgumentParser.ExitCode(process.terminationStatus)
101+
throw ArgumentParser.ExitCode(await processManager.terminationStatus)
80102
}
81103
}
82104
}

0 commit comments

Comments
 (0)