(* Copyright (C) 1992, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* Last modified on Tue Oct 13 15:50:33 PDT 1992 by muller *) UNSAFE MODULE File EXPORTS File; IMPORT Text, Ctypes, M3toC, Unix, Uuio, Uerror; REVEAL F = OBJECT METHODS close () RAISES {Error}; seek (pos: CARDINAL) RAISES {Error}; isaTTY (): BOOLEAN RAISES {Error}; isSeekable (): BOOLEAN RAISES {Error}; END BRANDED OBJECT fd: Ctypes.int; END; R = F OBJECT METHODS new (name: Text.T): R RAISES {CannotAccess, Error}; read (VAR a: ARRAY OF CHAR; VAR n: CARDINAL) RAISES {EOF, Error}; eof (): BOOLEAN RAISES ANY; END BRANDED OBJECT OVERRIDES new := newRead; close := close; seek := seek; isaTTY := isaTTY; isSeekable := isSeekable; read := read; END; W = F OBJECT METHODS new (name: Text.T): W RAISES {CannotAccess, Error}; write (READONLY a: ARRAY OF CHAR) RAISES {NoSpace, Error}; END BRANDED OBJECT OVERRIDES new := newWrite; close := close; seek := seek; isaTTY := isaTTY; isSeekable := isSeekable; write := write; END; PROCEDURE newRead (self: R; name: Text.T): R RAISES {CannotAccess, Error} = VAR fd: Ctypes.int; nm := M3toC.CopyTtoS (name); BEGIN fd := Unix.open (nm, Unix.O_RDONLY, 0); M3toC.FreeS (nm); IF fd = -1 THEN IF Uerror.errno = Uerror.EACCES THEN RAISE CannotAccess; ELSE RAISE Error; END; END; IF self = NIL THEN RETURN (NEW (R, fd := fd)); ELSE self.fd := fd; RETURN self; END; END newRead; PROCEDURE newWrite (self: W; name: Text.T): W RAISES {CannotAccess, Error} = VAR fd: Ctypes.int; nm := M3toC.CopyTtoS (name); BEGIN fd := Unix.open (nm, Unix.O_WRONLY + Unix.O_CREAT, Unix.Mrwrwrw); M3toC.FreeS (nm); IF fd = -1 THEN IF Uerror.errno = Uerror.EACCES THEN RAISE CannotAccess; ELSE RAISE Error; END; END; IF self = NIL THEN RETURN (NEW (W, fd := fd)); ELSE self.fd := fd; RETURN self; END; END newWrite; PROCEDURE read (self: R; VAR a: ARRAY OF CHAR; VAR n: CARDINAL) RAISES {EOF, Error} = VAR status: Ctypes.int; BEGIN status := Uuio.read (self.fd, ADR (a[0]), NUMBER (a)); IF status = 0 THEN RAISE EOF; ELSIF status = -1 THEN RAISE Error; ELSE n := status; END; END read; PROCEDURE write (self: W; READONLY a: ARRAY OF CHAR) RAISES {NoSpace, Error} = VAR status: Ctypes.int; BEGIN status := Uuio.write (self.fd, ADR (a[0]), NUMBER (a)); IF status = -1 THEN IF Uerror.errno = Uerror.ENOSPC THEN RAISE NoSpace; ELSE RAISE Error; END; ELSIF status # NUMBER (a) THEN RAISE Error; END; END write; PROCEDURE seek (self: F; pos: CARDINAL) RAISES {Error} = VAR status: Ctypes.int; BEGIN status := Unix.lseek (self.fd, pos, Unix.L_SET); IF status # 0 THEN RAISE Error; END; END seek; PROCEDURE isSeekable (self: F): BOOLEAN RAISES {Error} = VAR current, status: Ctypes.int; BEGIN current := Unix.tell (self.fd); status := Unix.lseek (self.fd, current, Unix.L_SET); RETURN status = current; END isSeekable; PROCEDURE isaTTY (self: F): BOOLEAN RAISES {Error} = BEGIN RETURN Unix.isatty (self.fd) = 1; END isaTTY; PROCEDURE close (self: F) RAISES {Error} = BEGIN IF self.fd >= 3 AND Unix.close (self.fd) # 0 THEN RAISE Error; END; END close; BEGIN END File.