Anton Kochkov
Anton Kochkov

Reputation: 1287

How to keep the pipe to another process opened

I am trying to talk with the bc instance through pipes, but with my code it runs the new instance every time. Is it possible to keep the connection persistent until I close it?

:- use_module(library(unix)).
:- use_module(library(process)).

read_result(Out, Result) :-
     read(Out, Result).

send_command(R, Command, Result) :-
     write(R.in, Command),
     nl(R.in),
     flush_output(R.in),
     read_result(R.out, Result).

% create structure with pid and in/out pipes
open_session(R) :-
    % pipe(In, Out),
    process_create(path(bc),
    % bc -q
        ["-q"],
        [stdin(pipe(In)),
        stdout(pipe(Out)),
        process(Pid)]),
    dict_create(R, bcinstance, [pid:Pid,in:In,out:Out]).

close_instance(R) :-
    close(R.in),
    close(R.out),
    process_kill(R.pid).

with_command(Command, O) :-
    open_session(R),
    send_command(R, Command, O),
    close_instance(R).

If I use with_command("2+3", O). it seems just waits for the input, instead of outputting "5" not sure why.

Upvotes: 2

Views: 202

Answers (1)

mat
mat

Reputation: 40768

First, a pipe does persist until one of the processes closes it.

Your example almost works as intended, except for one small problem:

read/2 expects a Prolog term, and then a dot. Since the process does not emit a ., read/2 waits for further input.

One solution: Use for example read_line_to_codes/2 instead of read/2:

read_result(Out, Codes) :-
     read_line_to_codes(Out, Codes).

Sample query:

?- with_command("2+3", O).
O = [53].

Verification:

?- X = 0'5.
X = 53.

It would be great to have read_line_to_chars/2, wouldn't it?

Upvotes: 2

Related Questions