1 (* IO.mod provides Read, Write, Errors procedures mapping onto 0, 1 and 2.
3 Copyright (C) 2001-2023 Free Software Foundation, Inc.
4 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
6 This file is part of GNU Modula-2.
8 GNU Modula-2 is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GNU Modula-2 is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. *)
27 IMPLEMENTATION MODULE IO ;
30 FROM StrLib IMPORT StrCopy ;
31 FROM SYSTEM IMPORT ADR, SIZE ;
32 FROM libc IMPORT read, write, system, isatty ;
34 FROM FIO IMPORT File, StdIn, StdOut, StdErr, WriteChar, ReadChar,
35 GetUnixFileDescriptor, FlushBuffer ;
37 FROM errno IMPORT geterrno, EINTR, EAGAIN ;
38 FROM ASCII IMPORT cr, eof, nl;
39 FROM termios IMPORT TERMIOS, Flag, InitTermios, KillTermios,
40 SetFlag, tcgetattr, tcsetattr, cfmakeraw,
41 tcsdrain, tcsnow, tcsflush ;
54 fdState: ARRAY [0..MaxDefaultFd] OF BasicFds ;
58 IsDefaultFd - returns TRUE if, fd, is 0, 1 or 2.
61 PROCEDURE IsDefaultFd (fd: INTEGER) : BOOLEAN ;
63 RETURN( (fd<=MaxDefaultFd) AND (fd>=0) )
67 PROCEDURE Read (VAR ch: CHAR) ;
81 r := read(GetUnixFileDescriptor(StdIn), ADR(ch), 1) ;
105 doWrite - performs the write of a single character, ch,
109 PROCEDURE doWrite (fd: INTEGER; f: File; ch: CHAR) ;
119 r := write(GetUnixFileDescriptor(f), ADR(ch), 1) ;
126 IF (r#EAGAIN) AND (r#EINTR)
141 PROCEDURE Write (ch: CHAR) ;
143 doWrite(1, StdOut, ch)
147 PROCEDURE Error (ch: CHAR) ;
149 doWrite(2, StdErr, ch)
154 setFlag - sets or unsets the appropriate flag in, t.
157 PROCEDURE setFlag (t: TERMIOS; f: Flag; b: BOOLEAN) ;
166 doraw - sets all the flags associated with making this
167 file descriptor into raw input/output.
170 PROCEDURE doraw (term: TERMIOS) ;
174 * termios_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
175 * | INLCR | IGNCR | ICRNL | IXON);
176 * termios_p->c_oflag &= ~OPOST;
177 * termios_p->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
178 * termios_p->c_cflag &= ~(CSIZE | PARENB);
179 * termios_p->c_cflag |= CS8;
181 setFlag(term, ignbrk, FALSE) ;
182 setFlag(term, ibrkint, FALSE) ;
183 setFlag(term, iparmrk, FALSE) ;
184 setFlag(term, istrip, FALSE) ;
185 setFlag(term, inlcr, FALSE) ;
186 setFlag(term, igncr, FALSE) ;
187 setFlag(term, icrnl, FALSE) ;
188 setFlag(term, ixon, FALSE) ;
190 setFlag(term, opost, FALSE) ;
192 setFlag(term, lecho, FALSE) ;
193 setFlag(term, lechonl, FALSE) ;
194 setFlag(term, licanon, FALSE) ;
195 setFlag(term, lisig, FALSE) ;
196 setFlag(term, liexten, FALSE) ;
198 setFlag(term, parenb, FALSE) ;
199 setFlag(term, cs8, TRUE)
204 dononraw - sets all the flags associated with making this
205 file descriptor into non raw input/output.
208 PROCEDURE dononraw (term: TERMIOS) ;
211 * we undo these settings, (although we leave the character size alone)
214 * termios_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
215 * | INLCR | IGNCR | ICRNL | IXON);
216 * termios_p->c_oflag &= ~OPOST;
217 * termios_p->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
218 * termios_p->c_cflag &= ~(CSIZE | PARENB);
219 * termios_p->c_cflag |= CS8;
221 setFlag(term, ignbrk, TRUE) ;
222 setFlag(term, ibrkint, TRUE) ;
223 setFlag(term, iparmrk, TRUE) ;
224 setFlag(term, istrip, TRUE) ;
225 setFlag(term, inlcr, TRUE) ;
226 setFlag(term, igncr, TRUE) ;
227 setFlag(term, icrnl, TRUE) ;
228 setFlag(term, ixon, TRUE) ;
230 setFlag(term, opost, TRUE) ;
232 setFlag(term, lecho, TRUE) ;
233 setFlag(term, lechonl, TRUE) ;
234 setFlag(term, licanon, TRUE) ;
235 setFlag(term, lisig, TRUE) ;
236 setFlag(term, liexten, TRUE)
240 PROCEDURE BufferedMode (fd: INTEGER; input: BOOLEAN) ;
247 fdState[fd].IsRaw := FALSE
249 term := InitTermios() ;
250 IF tcgetattr(fd, term)=0
255 r := tcsetattr(fd, tcsflush(), term)
257 r := tcsetattr(fd, tcsdrain(), term)
260 term := KillTermios(term)
264 PROCEDURE UnBufferedMode (fd: INTEGER; input: BOOLEAN) ;
271 fdState[fd].IsRaw := TRUE
273 term := InitTermios() ;
274 IF tcgetattr(fd, term)=0
279 result := tcsetattr(fd, tcsflush(), term)
281 result := tcsetattr(fd, tcsdrain(), term)
284 term := KillTermios(term)
289 EchoOn - turns on echoing for file descriptor, fd. This
290 only really makes sence for a file descriptor opened
291 for terminal input or maybe some specific file descriptor
292 which is attached to a particular piece of hardware.
295 PROCEDURE EchoOn (fd: INTEGER; input: BOOLEAN) ;
300 term := InitTermios() ;
301 IF tcgetattr(fd, term)=0
303 setFlag(term, lecho, TRUE) ;
306 result := tcsetattr(fd, tcsflush(), term)
308 result := tcsetattr(fd, tcsdrain(), term)
311 term := KillTermios(term)
316 EchoOff - turns off echoing for file descriptor, fd. This
317 only really makes sence for a file descriptor opened
318 for terminal input or maybe some specific file descriptor
319 which is attached to a particular piece of hardware.
322 PROCEDURE EchoOff (fd: INTEGER; input: BOOLEAN) ;
327 term := InitTermios() ;
328 IF tcgetattr(fd, term)=0
330 setFlag(term, lecho, FALSE) ;
333 result := tcsetattr(fd, tcsflush(), term)
335 result := tcsetattr(fd, tcsdrain(), term)
338 term := KillTermios(term)