Avoid deadlocks by draining all output streams concurrently
mainA subprocess can hang if its output or error pipes become full. On many systems, if you only read standardOutput and ignore standardError, the process will block once the error buffer (e.g., ~64 KB on Linux) is full, preventing the process from ever exiting.
Rule: Always drain every output stream you open.
To prevent deadlocks, use a TaskGroup to read both standardOutput and standardError concurrently so that neither pipe blocks the other.
_ = try await run(
.name("swift"),
arguments: ["build"],
input: .none,
output: .sequence,
error: .sequence
) { execution in
try await withThrowingTaskGroup(of: Void.self) { group in
group.addTask {
for try await line in execution.standardOutput.strings() {
print("out:", line)
}
}
group.addTask {
for try await line in execution.standardError.strings() {
print("err:", line)
}
}
try await group.waitForAll()
}
}