
/* popen2.q: clib pipes and process example showing how to create a
   bidirectional pipe to a child process (UNIX only) */

import system;

/* Create two unnamed pipes, one for the parent to read and the child to
   write, the other one for the child to read and the parent to write. */

popen2 CMD	= spawn2 CMD (P_IN, P_OUT) (C_IN, C_OUT)
		    where (P_IN, C_OUT) = pipe, (C_IN, P_OUT) = pipe;

/* Fork the child and redirect its standard input and output streams to the
   child's ends of the pipe. This is accomplished with dup2 SRC DEST which
   closes the file descriptor DEST and then makes DEST a copy of SRC. In the
   parent we use fdopen to open two new file objects for the parent's ends of
   the pipes. */

spawn2 CMD (P_IN, P_OUT) (C_IN, C_OUT)
		= close P_IN || close P_OUT ||
		  dup2 C_IN (fileno INPUT) || dup2 C_OUT (fileno OUTPUT) ||
		  exec "/bin/sh" ["/bin/sh", "-c", CMD] 
		    if fork = 0;
		= close C_IN || close C_OUT ||
		  (fdopen P_IN "r", fdopen P_OUT "w")
		    otherwise;

/* Here is an example: pipe a list of strings into the `sort' program and
   return the sorted list. */

mysort STRL	= do (fprintf OUT "%s\n") STRL || fclose OUT || digest IN
		    where (IN, OUT) = popen2 "sort";

digest IN	= [] if feof IN;
		= [freads IN|digest IN] otherwise;
