Using process_create for both input and output

Hi,

I am trying to open a process for both input and output, i.e. I want to be able to send it stuff and read back a result. So I tried the following code, which is supposed to start a Python interpreter, send it the expression “1+1”, and get the result back:

go :-
    process_create(path(python), [], 
      [stdin(pipe(In)), stdout(pipe(Out)), process(Pid)]),
    format("pid: ~w~n", [Pid]),
    writeln(In, "1+1"),
    flush_output(In),  % apparently necessary!
    read_line_to_string(Out, Result),
    writeln(Result).

This shows me the PID but hangs when I try to get the result. If I replace python with bash, and “1+1” with “ls”, it works fine. I wonder if it has anything to do with the fact that Python prints some lines when it starts, and bash does not? In any case, what am I doing wrong? Any tips welcome.

(By the way, I am just using Python as an example here; I am interested in a general solution rather than in talking to Python specifically…)

Oh, and a somewhat-related question: Is it possible in SWI-Prolog to have a stream that e.g. writes to both stdout and a file? (This would have been useful here for debugging purposes, etc.)

Thanks,

–Hans Nowak

Welcome,

While others such as @Jan will most likely give a more exact and helpful answer, one thing that you did not note and that might be of help is to look at the actual code for SWI-Prolog in the GitHub repository.

Be aware that some of the examples may be old as I recently learned but ask if you are not certain.

Hope this helps.

Here’s a hint:

$ python </dev/null
$ swipl
process_create(path(python), [], [stdin(null), stdout(pipe(Out))]), read_line_to_string(Out, Result).

Pipes in Unix are non-trivial if you have both stdin and stdout. It’s been ages since I’ve programmed with them, but my recollection is that Steven’s “Advanced Unix” book is a good source for avoiding the gotchas. (Stack exchange, of course, is another.)

Things to watch out for: buffering, the size of the pipe, blocking I/O.