0

I'm currently facing a strange problem. I would like to manage the execution of this simple binary with Python:

int main()
{
        char test[5];
        printf("Reading\n");
        fgets(test, 5, stdin);
        printf("Data read : %s\n", test);
}

What I have done so far is the following code:

child = subprocess.Popen("./example.bin", stdout=subprocess.PIPE, stdin=subprocess.PIPE)
child.stdout.readline()

My question is why does the readline() block forever? I mean, I know that the fgets() function will wait for inputs but in a standard terminal, the "Reading\n" string is correctly printed BEFORE it start waiting for user input.

Also, I though about the fgets() which is blocking on stdin which is, in fact, the same file descriptor as stdout (/dev/ttyX). Then, I understand that reading on stdin could block stdout. But, child.stdout is a BufferedIO and should have received the data sent by printf(). I tried to detach() stdout hoping that will cut the link with the file descriptor before doing a readline() on it without success.

I read a lot of thing in relation with pipes, tty and whatever. Unfortunately, it seems I'm missing something here. I also tried unsuccessfully lot of different parameters like bufsize=0, shell=True, etc. The communicate() function write data and close child.stdin which is not what I want to do (in my real program, I have more fgets()/printf() call).

Finally, if I write to child.stdin, flush it, check that the process have been terminated with poll(), child.stdout become finally readable.

Also, this deadlock problem seems to happen only when I pipe both stdin and stdout.

Does anyone know how to resolve this problem? How to read data that have been "printed" right before the reading?

Thank you in advance !

gagou7
  • 293
  • 3
  • 12
  • If you read [the `Popen` object documentation](https://docs.python.org/2/library/subprocess.html#popen-objects) you will see a warning that you should use [`communicate`](https://docs.python.org/2/library/subprocess.html#subprocess.Popen.communicate) instead of e.g. `stdout.read`. – Some programmer dude Oct 21 '15 at 13:59
  • 1
    @JoachimPileborg: `.communicate()` would help here because the input is finite and it does not depend on the child process' output but it is unrelated to the core issue: the buffering behavior may change if stdin/stdout are not connected to a tty. The warning in the subprocess' docs is about the case when the pipes are not consumed and therefore the child process hangs as soon as corresponding OS pipe buffers are full. `.readline()` would work here if the C program adjusts its stdout buffering mode. Read the answer to the duplicate question. – jfs Oct 21 '15 at 14:03

0 Answers0