streamProcess function
Runs executable and returns a stream of its interleaved stdout/stderr.
Implementation
Stream<String> streamProcess(String executable, List<String> args, {String? workingDirectory}) {
final controller = StreamController<String>();
Process? process;
StreamSubscription? sigintSub;
StreamSubscription? sigtermSub;
controller.onListen = () async {
try {
process = await Process.start(executable, args, workingDirectory: workingDirectory);
if (!Platform.isWindows) {
sigintSub = ProcessSignal.sigint.watch().listen((_) {
process?.kill(ProcessSignal.sigint);
exit(130);
});
sigtermSub = ProcessSignal.sigterm.watch().listen((_) {
process?.kill(ProcessSignal.sigterm);
exit(143);
});
}
int active = 2;
void done() {
active--;
if (active == 0) {
sigintSub?.cancel();
sigtermSub?.cancel();
controller.close();
}
}
process!.stdout.transform(utf8.decoder).transform(const LineSplitter()).listen(
controller.add,
onDone: done,
onError: controller.addError,
);
process!.stderr.transform(utf8.decoder).transform(const LineSplitter()).listen(
controller.add,
onDone: done,
onError: controller.addError,
);
} catch (e) {
controller.addError(e);
controller.close();
}
};
controller.onCancel = () {
sigintSub?.cancel();
sigtermSub?.cancel();
process?.kill();
};
return controller.stream;
}