(****************************************************************) (* *) (* 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.