rw/src/Common/Stdio.m3


Copyright (C) 1994, Digital Equipment Corp.

MODULE Stdio;

IMPORT File, FileRd, FileWr, OSError, Process, Thread, Wr, WrClass;
**************************************************************** The shutdown routine used to call Unsafe{Rd,Wr}.FastClose to flush and close the streams. But, it's an error to close the file descriptors that we did't open. So, we'll just flush. PROCEDURE ShutDown () = <* FATAL Thread.Alerted *> BEGIN IF stdin # NIL THEN TRY UnsafeRd.FastClose (stdin); EXCEPT Rd.Failure => END; END; IF stdout # NIL THEN TRY UnsafeWr.FastClose (stdout); EXCEPT Wr.Failure => END; END; IF stderr # NIL THEN TRY UnsafeWr.FastClose (stderr); EXCEPT Wr.Failure => END; END; END ShutDown; *********************************************************************

PROCEDURE ShutDown () =
  (* Note that this routine is unsafe.  It calls flush methods
     without acquiring the locks.  We don't acquire the locks
     because it can cause a deadlock when we're trying to
     crash the program from an arbitrary state. *)
  BEGIN
    TRY
      IF (stdout # NIL) AND (NOT stdout.closed) THEN stdout.flush (); END;
      IF (stderr # NIL) AND (NOT stderr.closed) THEN stderr.flush (); END;
    EXCEPT Thread.Alerted, Wr.Failure =>
      (* oh well, we tried. *)
    END;
  END ShutDown;

BEGIN
  stdin  := NIL;
  stdout := NIL;
  stderr := NIL;
  bufferedStderr := NIL;

  <*FATAL OSError.E*>
  VAR hIn, hOut, hErr: File.T;
  BEGIN
    Process.GetStandardFileHandles(stdin:=hIn, stdout:=hOut, stderr:=hErr);
    IF hIn # NIL THEN
      stdin := NEW(FileRd.T).init(hIn);
    END;
    IF hOut # NIL THEN
      stdout := NEW(FileWr.T).init(hOut, buffered := TRUE);
    END;
    IF hErr # NIL THEN
      stderr := NEW(FileWr.T).init(hErr, buffered := FALSE);
      bufferedStderr := NEW(FileWr.T).init(hErr, buffered := TRUE);
    END;
  END;

  Process.RegisterExitor (ShutDown);
END Stdio.