% $Id: preface.tex,v 1.1.1.2 2004/10/04 17:25:13 nthiery Exp $
\section*{The library \Mex{IPC}}

\eng{
  
  The \Mup[IPC,firstpage]{IPC} library provides various functions for
  Inter-Process Communications, and child process handling.
  
  The library functions are called using the library name \Mex{IPC}
  and the name of the function. E.g., use
  \begin{Mvin}{test=false}
IPC::popen("echo coucou", "r")
  \end{Mvin}
  to read line by line the output of a shell command. This mechanism
  avoids naming conflicts with other library functions.
  
  If this is found to be inconvenient, then the routines of the
  \Mex{IPC} library may be exported via \Mup{export}. E.g.,\ after
  calling
  \begin{Mvin}{test=false}
export(IPC, popen)
  \end{Mvin}
  the function \Mup{IPC::popen} may be called directly:
  \begin{Mvin}{test=false}
popen("echo coucou", "r")
  \end{Mvin}
  All the routines of the \Mup[IPC,firstpage]{IPC} library are
  exported simultaneously by
  \begin{Mvin}{test=false}
export(IPC)
  \end{Mvin}
  
  The functions and sub-libraries available in the
  \Mup[IPC,firstpage]{IPC} library can be listed using
  \begin{Mvin}{test=false}
info(IPC)
  \end{Mvin}
  }

\eng{\subsection*{Examples}}

\eng{In this section, we pick a few sample applications at random.
  First, we \Mup{export} the \Mup[IPC,firstpage]{IPC} library
  to save us some typing:}%
\begin{Mexin}
export(IPC):
\end{Mexin}

\eng{In our first example, we run a shell command, and read the
  output line by line:}
\begin{Mexin}
child := popen("echo coucou1; echo coucou2", "r"):
getline(child);
getline(child);
getline(child);
close(child):
\end{Mexin}
\begin{Mexout}
                           "coucou1"

                           "coucou2"
\end{Mexout}
\eng{Note that there is no output for the last call to getline.
  Indeed, after the end of output, getline returns null().}

\eng{We redo the same thing, but at a lower level. Accessing directly
  the streams is a \emph{little} bit faster if efficiency is at a
  premium.  This is also required if one wants to read from the
  standard error stream of the child \Mex{slave::stderr(child)}:}
\begin{Mexin}
child := popen("echo coucou1; echo coucou2", "r"):
pid := slave::pid(child):
childout := slave::stdout(child):
getline(childout);
getline(childout);
getline(childout);
close(childout):
waitpid(pid):
\end{Mexin}
\begin{Mexout}
                           "coucou1"

                           "coucou2"
\end{Mexout}

\eng{We demonstrate how to run some computations in a separate \mupad
  process:}
\begin{Mexin}
child := popen2("mupad -S -P pew"):
putline(child, "setuserinfo(NIL):"):
putline(child, "fprint(Unquoted, 0, 1+1):"):
text2expr(getline(child));
putline(child, "fprint(Unquoted, 0, 7!):"):
text2expr(getline(child));
putline(child, "fprint(Unquoted, 0, expand((x+1)^7)):"):
text2expr(getline(child));
close(child):
\end{Mexin}
\begin{Mexout}
                               2

                             5040

       7      6       5       4       3       2
      x  + 7 x  + 21 x  + 35 x  + 35 x  + 21 x  + 7 x + 1
\end{Mexout}
\eng{This allow for some basic parallelism on a multi-processor
  machine, or on several machines by using ssh.}

\eng{Here we run some computations with GAP:}
\begin{Mexin}
child := popen2("gap -b -q -n"):
putline(child, "1+1;"):
text2expr(getline(child));
putline(child, "G := Group((1,2,3,4));"):
getline(child):
putline(child, "Size(G);"):
text2expr(getline(child));
putline(child, "IsSolvable(G);"):
getline(child);
\end{Mexin}
\begin{Mexout}
                               2

                               4

                            "true"
\end{Mexout}

\eng{To conclude, we show how to create and use a very crude maple
  slave. Of course, this hack is not robust to errors, and only simple
  expressions can be manipulated. But in some easy cases this can
  still be useful.}
\begin{Mexin}
domain maple
    child    :=
    proc()
        local child;
    begin
        child := IPC::popen2("maple -q");
        IPC::putline(child, "kernelopts(printbytes=false):");
        child;
    end_proc();
      
    childin  := IPC::slave::stdin(dom::child);
    childout := IPC::slave::stdout(dom::child);

    new :=
    proc(e: DOM_STRING): DOM_STRING
    begin
        IPC::putline(dom::childin, "lprint(".e."):");
        return(IPC::getline(dom::childout));
    end_proc;
begin
end:
maple("1+1");
text2expr(maple("expand((1+x)^7)"))
\end{Mexin}
\begin{Mexout}
                              "2"

                    2       3       4       5      6    7
      1 + 7 x + 21 x  + 35 x  + 35 x  + 21 x  + 7 x  + x
\end{Mexout}
%%% Local Variables: 
%%% mode: latex
%%% TeX-master: main
%%% TeX-master: t
%%% End: 
