I\'m trying to write a python program that is able to interact with other programs. That means sending stdin and receiving stdout data. I cannot use pexpect (although it definit
First of all, os.read
does block, contrary to what you state. However, it does not block after select
. Also os.read
on a closed file descriptor always returns an empty string, that you might want to check for.
The real problem however is that the master device descriptor is never closed, thus the final select
is the one that will block. In a rare race condition, the child process has exited between select
and process.poll()
and your program exits nicely. Most of the time however the select blocks forever.
If you install the signal handler as proposed by izhak all hell breaks loose; whenever a child process is terminated, the signal handler is run. After the signal handler is run, the original system call in that thread cannot be continued, so that syscall invocation returns nonzero errno, which often results in some random exception being thrown in python. Now, if elsewhere in your program you use some library with any blocking system calls that do not know how to handle such exceptions, you are in a big trouble (any os.read
for example anywhere can now throw an exception, even after a successful select
).
Weighing having random exceptions thrown anywhere against polling a bit, I don't think the timeout on select
does not sound that bad idea. Your process would still hardly be the only (slow) polling process on the system anyway.