(****************************************************************)
(*                                                              *)
(*         Gardens Point Modula-2 Library Definition            *)
(*                                                              *)
(*                                                              *)
(*     (c) Copyright 1996 Faculty of Information Technology     *)
(*              Queensland University of Technology             *)
(*                                                              *)
(*     Permission is granted to use, copy and change this       *)
(*     program as long as the copyright message is left intact  *)
(*                                                              *)
(****************************************************************)

FOREIGN DEFINITION MODULE PipeUtilities;

  IMPORT IMPLEMENTATION FROM "pipeutilities.o";

  FROM UxFiles IMPORT File;
  FROM Types IMPORT Int32;

  CONST input  = 0; output = 1; stderr = 2;

  TYPE  FDPair = ARRAY [input .. output] OF Int32;

  PROCEDURE GetPipe(VAR pipeFDs : FDPair);
  (* Opens a pair of file descriptors with the pipe ends in them *)

  PROCEDURE ClosePipe(pipeFD : FDPair);
  (* Closes both descriptors of the given pipe  *)

(*
 *  The next procedures connect an input or output stream (UxFiles.File) 
 *  to one end of the pipe, the unused end is closed. Use UxFiles 
 *  operations on the stream, and call UxFiles.Close(stream) to finish.
 *)

  PROCEDURE FileInFromPipe(    pipeFD : FDPair;
			   VAR stream : File;
			   VAR done   : BOOLEAN);

  PROCEDURE FileOutToPipe (    pipeFD : FDPair;
			   VAR stream : File;
			   VAR done   : BOOLEAN);

(*
 *  The next procedures attach the standard input or output streams to 
 *  the opened pipe. Terminal, InOut, and StdError may then be used.
 *)

  PROCEDURE InputFrom(pipe : FDPair);
  (* Dups the nominated pipe to standard input  *)

  PROCEDURE OutputTo(pipe : FDPair);
  (* Dups the nominated pipe to standard output *)

  PROCEDURE ErrorOutTo(pipe : FDPair);
  (* Dups the nominated pipe to standard error  *)

  (* typical usage : 
   *
   *	FROM PipeUtilities IMPORT 
   *		FDPair, GetPipe, ClosePipe, InputFrom, OutputTo;
   *	FROM UxProcesses IMPORT Fork, Execp, Wait;
   *	FROM BuildArgs IMPORT Arg2;
   *	  VAR  pip1 : FDPair;
   *	  ...
   *	  GetPipe(pip1);
   *	  IF Fork() = 0 THEN (* in child 1 here *)
   *	    OutputTo(pip1);  (* copy pipe desc  *)
   *	    ClosePipe(pip1); (* close original  *)
   *	    Execp("cat",Arg2("cat","file.mod"));
   *	  ELSIF Fork() = 0 THEN (* child 2 here *)
   *	    InputFrom(pip1); (* copy pipe desc  *)
   *	    ClosePipe(pip1); (* close original  *)
   *	    Execp("grep",Arg2("grep","foo"));
   *	  ELSE (* in parent process here *)
   *	    ClosePipe(pip1); (* so end of child 2 will wake child 1 *)
   *	    id := Wait(res); id := Wait(res); (* wait for both *)
   *	  END;
   *)
END PipeUtilities.