Connecting streams to process_create/3

I’m using SWI-Prolog version 8.1.6

Is it possible to connect an already-open stream to the input/output/error of a process using process_create/3? I see the stdin/stderr/stdout arguments, but they only give “fresh” pipes.

i.e., is there some way to do something like


test(Status) :-
    setup_call_cleanup(
        ( open("foo_out", write, Out),
          open("foo_in", read, In),
          open("foo_err", write, Err) ),
        ( process_create(path(cat), [],
                         [ process(Pid),
% below gives
% error: `process_stream' expected, found <stream>(...)
% if I try stdout(pipe(Out)), then it's "Uninstantiated argument expected"
                           stdin(In),
                           stdout(Out),
                           stderr(Err) ]),
          process_wait(Pid, Status) ),
        ( close(Out), close(In), close(Err) )
    ).

and have the files foo_out, foo_in, and foo_err used as the output, input, and error of some process?
Failing this working directly, is there some simple way to just connect the streams returned by giving stdout(pipe(NewOut)) to the stream I’ve opened?

2 Likes

The API comes from SICStus. If the streams come from a file (or socket) we should technically be able to pass this on to the child without Prolog involvement. In the general case we cannot as the stream may be connected to some memory area in the Prolog process. If it concerns files you can in most cases pass the proper arguments to the process (always if you use the shell as helper).

The typical solution is to use threads to send or read the various inputs. That works for the general case, but is inefficient for files/sockets.

I would not be against adding such functionality. It is not on my shortlist though.

1 Like

Created a pull request to allow passing already-opened file streams to process_create/3: https://github.com/SWI-Prolog/packages-clib/pull/26

1 Like

Thanks. Merged!

1 Like

And Jan has merged a unit test case:

1 Like