0

I made a simple model of what I am doing in a bigger application.

I am trying to figure out how to communicate with the Popen process so that it is going to wait for io when required, and the user could provide that input. How to do it and is it even possible?

Project files:

scanftest.c

#include <stdio.h>

int main(void) {
    
    int x = 1;
    
    printf("Please, enter integer to echo.\n");

    scanf("%d", &x);
    
    printf("%d\n", x);
    
    return 0;
}

minirunner.py

from subprocess import *  # run, Popen, PIPE

run("gcc -o scanftest scanftest.c", shell=True)

x = Popen("./scanftest", stdin=PIPE, stdout=PIPE, stderr=PIPE)

while True:

    if x.returncode:
        break

    x.stdin.write(input("stdin> ").encode('utf-8'))

    print(x.stdout.read().decode('utf-8'))

print("Done")

When I run minirunner.py, this is what happens:

stdin> 10

I then press ^C and see the following

^CTraceback (most recent call last):
  File "minirunner.py", line 14, in <module>
    print(x.stdout.read().decode('utf-8'))
KeyboardInterrupt

Seems like it is stuck when trying to read()

Meanwhile I expected and desired something like that:

stdin> 10
Please, enter integer to echo.
stdin> 10
10
Done.

Potentially I would like to deal with scanf in loops. But as You can see, even simple example fails.

Andrey Kachow
  • 936
  • 7
  • 22
  • i'm not sure but `input()` gives string without `\n` - so you send value without `\n` but `scanf()` may wait for data with `\n` – furas Mar 18 '22 at 03:49
  • @furas, yeah, Thanks for noticing. I tried concatenating with `\n`. Didn't make much difference. But thanks! – Andrey Kachow Mar 18 '22 at 03:51

1 Answers1

0

It needs two things

  1. send with \n so scanf will know where is end of data.

  2. use x.stdin.flush() to inform buffer that it can send data.

from subprocess import *  # run, Popen, PIPE

run("gcc -o scanftest scanftest.c", shell=True)

x = Popen("./scanftest", stdin=PIPE, stdout=PIPE)

while True:

    if x.returncode:
        break

    text = input("stdin> ") + '\n'
    
    x.stdin.write(text.encode('utf-8'))
    x.stdin.flush()

    print(x.stdout.read().decode('utf-8'))

print("Done")
furas
  • 134,197
  • 12
  • 106
  • 148