(****************************************************************)
(*                                                              *)
(*         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 UxHandles;
  IMPORT IMPLEMENTATION FROM "uxhandles.o";

  FROM UxFiles IMPORT File, OpenMode;

(* 
 *  This module complements UxFiles by giving stream access to
 *  handles including standard handles --- stdIn, stdOut, stdErr
 *
 *  BEWARE that streams attached to standard handles stdOut and
 *  stdErr may require a FlushStream or CloseStream call to
 *  force output to appear on interactive terminals
 *
 *  TYPE UxFiles.OpenMode = (ReadOnly, WriteOnly, ReadWrite);
 *)

  TYPE	FileDesc = INTEGER [-1 .. 32767];
  CONST	error  = -1;
	stdIn  = 0;
	stdOut = 1;
	stdErr = 2;

  PROCEDURE OpenFileHandle(path : ARRAY OF CHAR;
			   mode : OpenMode) : FileDesc;
(*
 *  precondition  : path must be a constant string, or be nul
 *		    terminated if a variable array of chars.
 *  postcondition : returns error if cannot be opened, else
 *		    the opened file handle.
 *)

  PROCEDURE CloseHandle(handle : FileDesc; 
			VAR ok : BOOLEAN);
(*
 *  the file descriptor "handle is closed
 *)

  PROCEDURE StreamOfHandle(fd : FileDesc) : File;
  PROCEDURE CloseStream(stream : File; VAR ok : BOOLEAN);
  PROCEDURE FlushStream(stream : File; VAR ok : BOOLEAN);
(*
 *  These procedures open, close and flush a stream on the 
 *  nominated file handle, allowing UxFiles procs to be used.
 *  CloseStream is identical to UxFiles.Close
 *  FlushStream is often needed to force output
 * 
 *  Example -- to place a stream on a standard handle
 *
 *	stdInFile := StreamOfHandle(stdIn);
 *)

  PROCEDURE RedirectHandle(old   : FileDesc;	(* overwritten *)
			   new   : FileDesc;	(* replacement *)
			VAR save : FileDesc;	(* copy of old *)
			VAR done : BOOLEAN);
(*
 *  precondition  : old and new are open file descriptors.
 *  postcondition : input/output sent to "old" will go to the
 *		    stream previously associated with "new"
 *		    The descriptor "new" is closed. The handle
 *		    previously "old" is duplicated in "save"
 *)

  PROCEDURE RestoreHandle (old   : FileDesc;	(* overwritten *)
			   saved : FileDesc;	(* replacement *)
			VAR done : BOOLEAN);
(*
 *  precondition  : old and new are open file descriptors.
 *  postcondition : input/output sent to "old" will go to the
 *		    stream previously associated with "saved"
 *		    The descriptor "saved" is closed, and the
 *		    previous handle "old" is closed also
 *
 *  Example of typical use -- redirecting standard error
 *
 *	newFD := Open("foo.err", WriteOnly);
 *	  -- and check that newFD is not error ...
 *	RedirectHandle(stdErr,newFD,errSav,ok);
 *	(* closes newFD, and does 2> foo.err *)
 *	  -- now fork, exec or whatever ...
 *	RestoreHandle(stdErr,errSav,ok);
 *	(* stderr restored, foo.err is closed *)
 *)

END UxHandles.