No way to distinguish if IOSink is writable

void forwardLogs(d) {
  if (d.startsWith(RegExp('\\[(LOG|ERROR|HANDLE|LISTEN_PORT)\\]')))
      return;
  }

  final encoded = utf8.encode(d);
  p.stdin.add(encoded);
}

final p = await Process.run('executable', []);
final sub = someStream.listen(forwardLogs);

p.exitCode.then((_) => sub.cancel());

The code above throws Broken pipe exception, which is I believe an indicator of process being terminated (stdin is closed by the time forwardLogs is executed), which means p.exitCode callback is being executed after forwardLogs. What’s the right way to distinguish if p.stdin is writable?

Author: Fantashit

1 thought on “No way to distinguish if IOSink is writable

  1. The only way to know if a pipe (in this case stdin) is writable is writing to it and the operation may succeed or fail. This is how the underlying operating system primitives work. Even if you were able to ask the OS whether the pipe is broken (no readers) before writing to the pipe, this is subject to race conditions (the other process could have exited) and isn’t useful. In Dart, you need to handle the broken pipe exception if it happens.

    Note the distinction between a broken pipe condition (all reading handles to the pipe are closed) and a process exit. These often happen together for simple programs but are not simultaneous and depending on the process, each condition can happen without the other happening. For instance, a process can close its stdin file descriptor without dying. Likewise, the child process might pass the stdin pipe to grand child processes, and then exit, but the pipe can will be written to because some process still have the reading end open.

    I’m closing this issue as there’s no action items for the Dart project. If the process in question can exit on its own, your code will need to handle the exitCode becoming available or a broken pipe exception happening when writing to its stdin, whatever comes first.

Comments are closed.