
exec(+Command, ?Streams, -Pid)

   A child process Command is forked, its standard streams are connected to
Streams and its process ID is Pid.



Arguments
   +Command            String, atom or list of atomic terms.
   +Streams            List, partial list, nil or a variable.
   ?Pid                Integer or a variable.

Type
   Operating System

Description
   This predicate is used to fork a child process and to set up pipes
   to its standard streams.  After the process is forked, ECLiPSe
   continues normally, without waiting for the child to terminate.


   If Command is a string or atom, the first word in Command specifies
   the program to be executed, following words are its command-line
   arguments.  If Command is a list, the first list element specifies
   the program to be executed and the subsequent elements are its
   arguments.  The latter form is preferred since it avoids problems
   with argument quoting.


   By specifying the Streams argument it is possible to control which of
   the process' standard streams are connected to ECLiPSe streams.  The
   form of Streams is [Stdin, Stdout, Stderr].  If some of these streams
   are specified and not null, a pipe is opened which connects the standard
   stream of the child process with the specified ECLiPSe stream, e.g.
   Stdin must be an output stream because it is connected to the standard
   input of the child process.  If the list Streams is shorter, only the
   specified streams are connected with a pipe.  The streams can be
   specified like for open/3.  If the stream is a variable, it is bound to
   the physical stream number, if it is an atom different from null, that
   symbolic stream is used.  Specifying a null stream means that no pipe is
   set up for this stream.


   Each stream can also be specified as sigio(Stream) (BSD systems only).
   In this case a pipe is set up to the stream Stream and in addition the
   pipe is instructed to send the signal io each time new data appears in
   it.  In this way the two processes can communicate in a truly
   asynchronous way.  When one process sends data to the other one, the
   interrupt handler is invoked and it can read and process the data.  When
   it finishes, it can continue where it was interrupted.


   After forking the process, Pid is unified with its process ID, which can
   be used e.g.  in wait/2 or kill/2.  If the exec system call in the child
   process failed, the child exits with status 128 + errno.




Resatisfiable
      No.

Fail Conditions
      None.



Exceptions
     4 --- Command is not instantiated.
     5 --- Command is instantiated, but not to a string or an atom.
     5 --- Streams is instantiated, but not to a list.
     5 --- A stream in Streams is instantiated, but not to an atom or a    sigio structure.
     5 --- Pid is instantiated.
   170 --- System error, it was not possible to fork the child.
   192 --- The specified stream is not open in the appropriate mode.

Examples
   
% execute an ls-command

    ?- exec([ls,"-C"], [null, out], Pid).
    Pid = 10885
    yes.

    ?- repeat, get(out,X), (X = -1 -> close(out) ; put(X), fail).
    aux.o           coroutine.pl    kegi.pl         sepia.o
    bsi.pl          cprolog.pl      lint.pl         sorts.pl
    cio.pl          history.pl      lists.pl        strings.pl
    cn.pl           k_env.pl        quintus.pl      t_all.pl

    X = -1

    ?- wait(S, Pid).
    Pid = 10885
    S = 10885
    yes.


% execute another eclipse

    ?- argv(0,Ecl),	% get name of the eclipse executable
       exec([Ecl,"-e","read(X),Y is X*X,printf('%w. %b',[Y])"], [in,out], P).

    E = "/usr/local/eclipse/5.1.1/bin/sparc_sunos5/eclipse.exec"
    P = 10741
    yes.

    [eclipse 2]: printf(in, '%w. %b', [12]), read(out, Result).
    Result = 144
    yes.

    [eclipse 3]: close(in), close(out), wait(10741, S).
    S = 0
    yes.


Error:
      exec(S, [], Pid).          (Error 4).
      exec(ls, null, Pid).       (Error 5).
      exec(chipc, [1], P).       (Error 5).
      exec(date, [input], P).    (Error 192).





See Also
   exec / 2, exec_group / 3, wait / 2, kill / 2, sh / 1, system / 1, open / 3
