1 /* do not edit automatically generated by mc from IO. */
2 /* IO.mod provides Read, Write, Errors procedures mapping onto 0, 1 and 2.
4 Copyright (C) 2001-2024 Free Software Foundation, Inc.
5 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
7 This file is part of GNU Modula-2.
9 GNU Modula-2 is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
14 GNU Modula-2 is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 Under Section 7 of GPL version 3, you are granted additional
20 permissions described in the GCC Runtime Library Exception, version
21 3.1, as published by the Free Software Foundation.
23 You should have received a copy of the GNU General Public License and
24 a copy of the GCC Runtime Library Exception along with this program;
25 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
26 <http://www.gnu.org/licenses/>. */
31 # if !defined (PROC_D)
33 typedef void (*PROC_t
) (void);
34 typedef struct { PROC_t proc
; } PROC
;
54 # include "Gtermios.h"
56 # define MaxDefaultFd 2
57 typedef struct IO_BasicFds_r IO_BasicFds
;
59 typedef struct IO__T1_a IO__T1
;
61 struct IO_BasicFds_r
{
66 struct IO__T1_a
{ IO_BasicFds array
[MaxDefaultFd
+1]; };
67 static IO__T1 fdState
;
70 IsDefaultFd - returns TRUE if, fd, is 0, 1 or 2.
73 extern "C" void IO_Read (char *ch
);
76 doWrite - performs the write of a single character, ch,
80 extern "C" void IO_Write (char ch
);
83 doWrite - performs the write of a single character, ch,
87 extern "C" void IO_Error (char ch
);
88 extern "C" void IO_UnBufferedMode (int fd
, bool input
);
89 extern "C" void IO_BufferedMode (int fd
, bool input
);
92 EchoOn - turns on echoing for file descriptor, fd. This
93 only really makes sence for a file descriptor opened
94 for terminal input or maybe some specific file descriptor
95 which is attached to a particular piece of hardware.
98 extern "C" void IO_EchoOn (int fd
, bool input
);
101 EchoOff - turns off echoing for file descriptor, fd. This
102 only really makes sence for a file descriptor opened
103 for terminal input or maybe some specific file descriptor
104 which is attached to a particular piece of hardware.
107 extern "C" void IO_EchoOff (int fd
, bool input
);
110 IsDefaultFd - returns TRUE if, fd, is 0, 1 or 2.
113 static bool IsDefaultFd (int fd
);
116 doWrite - performs the write of a single character, ch,
120 static void doWrite (int fd
, FIO_File f
, char ch
);
123 setFlag - sets or unsets the appropriate flag in, t.
126 static void setFlag (termios_TERMIOS t
, termios_Flag f
, bool b
);
129 doraw - sets all the flags associated with making this
130 file descriptor into raw input/output.
133 static void doraw (termios_TERMIOS term
);
136 dononraw - sets all the flags associated with making this
137 file descriptor into non raw input/output.
140 static void dononraw (termios_TERMIOS term
);
146 static void Init (void);
150 IsDefaultFd - returns TRUE if, fd, is 0, 1 or 2.
153 static bool IsDefaultFd (int fd
)
155 return (fd
<= MaxDefaultFd
) && (fd
>= 0);
156 /* static analysis guarentees a RETURN statement will be used before here. */
157 __builtin_unreachable ();
162 doWrite - performs the write of a single character, ch,
166 static void doWrite (int fd
, FIO_File f
, char ch
)
170 if (fdState
.array
[fd
].IsRaw
)
172 /* avoid dangling else. */
173 if (! fdState
.array
[fd
].IsEof
)
177 r
= static_cast<int> (libc_write (FIO_GetUnixFileDescriptor (f
), &ch
, static_cast<size_t> (1)));
184 /* avoid dangling else. */
185 r
= errno_geterrno ();
186 if ((r
!= errno_EAGAIN
) && (r
!= errno_EINTR
))
188 fdState
.array
[fd
].IsEof
= true;
197 FIO_WriteChar (f
, ch
);
203 setFlag - sets or unsets the appropriate flag in, t.
206 static void setFlag (termios_TERMIOS t
, termios_Flag f
, bool b
)
208 if (termios_SetFlag (t
, f
, b
))
214 doraw - sets all the flags associated with making this
215 file descriptor into raw input/output.
218 static void doraw (termios_TERMIOS term
)
222 * termios_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
223 * | INLCR | IGNCR | ICRNL | IXON);
224 * termios_p->c_oflag &= ~OPOST;
225 * termios_p->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
226 * termios_p->c_cflag &= ~(CSIZE | PARENB);
227 * termios_p->c_cflag |= CS8;
229 setFlag (term
, termios_ignbrk
, false);
230 setFlag (term
, termios_ibrkint
, false);
231 setFlag (term
, termios_iparmrk
, false);
232 setFlag (term
, termios_istrip
, false);
233 setFlag (term
, termios_inlcr
, false);
234 setFlag (term
, termios_igncr
, false);
235 setFlag (term
, termios_icrnl
, false);
236 setFlag (term
, termios_ixon
, false);
237 setFlag (term
, termios_opost
, false);
238 setFlag (term
, termios_lecho
, false);
239 setFlag (term
, termios_lechonl
, false);
240 setFlag (term
, termios_licanon
, false);
241 setFlag (term
, termios_lisig
, false);
242 setFlag (term
, termios_liexten
, false);
243 setFlag (term
, termios_parenb
, false);
244 setFlag (term
, termios_cs8
, true);
249 dononraw - sets all the flags associated with making this
250 file descriptor into non raw input/output.
253 static void dononraw (termios_TERMIOS term
)
256 * we undo these settings, (although we leave the character size alone)
259 * termios_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
260 * | INLCR | IGNCR | ICRNL | IXON);
261 * termios_p->c_oflag &= ~OPOST;
262 * termios_p->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
263 * termios_p->c_cflag &= ~(CSIZE | PARENB);
264 * termios_p->c_cflag |= CS8;
266 setFlag (term
, termios_ignbrk
, true);
267 setFlag (term
, termios_ibrkint
, true);
268 setFlag (term
, termios_iparmrk
, true);
269 setFlag (term
, termios_istrip
, true);
270 setFlag (term
, termios_inlcr
, true);
271 setFlag (term
, termios_igncr
, true);
272 setFlag (term
, termios_icrnl
, true);
273 setFlag (term
, termios_ixon
, true);
274 setFlag (term
, termios_opost
, true);
275 setFlag (term
, termios_lecho
, true);
276 setFlag (term
, termios_lechonl
, true);
277 setFlag (term
, termios_licanon
, true);
278 setFlag (term
, termios_lisig
, true);
279 setFlag (term
, termios_liexten
, true);
287 static void Init (void)
291 for (fdi
=0; fdi
<=MaxDefaultFd
; fdi
++)
293 fdState
.array
[fdi
].IsEof
= false;
294 fdState
.array
[fdi
].IsRaw
= false;
300 IsDefaultFd - returns TRUE if, fd, is 0, 1 or 2.
303 extern "C" void IO_Read (char *ch
)
307 FIO_FlushBuffer (FIO_StdOut
);
308 FIO_FlushBuffer (FIO_StdErr
);
309 if (fdState
.array
[0].IsRaw
)
311 if (fdState
.array
[0].IsEof
)
319 r
= static_cast<int> (libc_read (FIO_GetUnixFileDescriptor (FIO_StdIn
), ch
, static_cast<size_t> (1)));
326 /* avoid dangling else. */
327 r
= errno_geterrno ();
328 if (r
!= errno_EAGAIN
)
330 fdState
.array
[0].IsEof
= true;
340 (*ch
) = FIO_ReadChar (FIO_StdIn
);
346 doWrite - performs the write of a single character, ch,
350 extern "C" void IO_Write (char ch
)
352 doWrite (1, FIO_StdOut
, ch
);
357 doWrite - performs the write of a single character, ch,
361 extern "C" void IO_Error (char ch
)
363 doWrite (2, FIO_StdErr
, ch
);
366 extern "C" void IO_UnBufferedMode (int fd
, bool input
)
368 termios_TERMIOS term
;
371 if (IsDefaultFd (fd
))
373 fdState
.array
[fd
].IsRaw
= true;
375 term
= termios_InitTermios ();
376 if ((termios_tcgetattr (fd
, term
)) == 0)
381 result
= termios_tcsetattr (fd
, termios_tcsflush (), term
);
385 result
= termios_tcsetattr (fd
, termios_tcsdrain (), term
);
388 term
= termios_KillTermios (term
);
391 extern "C" void IO_BufferedMode (int fd
, bool input
)
393 termios_TERMIOS term
;
396 if (IsDefaultFd (fd
))
398 fdState
.array
[fd
].IsRaw
= false;
400 term
= termios_InitTermios ();
401 if ((termios_tcgetattr (fd
, term
)) == 0)
406 r
= termios_tcsetattr (fd
, termios_tcsflush (), term
);
410 r
= termios_tcsetattr (fd
, termios_tcsdrain (), term
);
413 term
= termios_KillTermios (term
);
418 EchoOn - turns on echoing for file descriptor, fd. This
419 only really makes sence for a file descriptor opened
420 for terminal input or maybe some specific file descriptor
421 which is attached to a particular piece of hardware.
424 extern "C" void IO_EchoOn (int fd
, bool input
)
426 termios_TERMIOS term
;
429 term
= termios_InitTermios ();
430 if ((termios_tcgetattr (fd
, term
)) == 0)
432 setFlag (term
, termios_lecho
, true);
435 result
= termios_tcsetattr (fd
, termios_tcsflush (), term
);
439 result
= termios_tcsetattr (fd
, termios_tcsdrain (), term
);
442 term
= termios_KillTermios (term
);
447 EchoOff - turns off echoing for file descriptor, fd. This
448 only really makes sence for a file descriptor opened
449 for terminal input or maybe some specific file descriptor
450 which is attached to a particular piece of hardware.
453 extern "C" void IO_EchoOff (int fd
, bool input
)
455 termios_TERMIOS term
;
458 term
= termios_InitTermios ();
459 if ((termios_tcgetattr (fd
, term
)) == 0)
461 setFlag (term
, termios_lecho
, false);
464 result
= termios_tcsetattr (fd
, termios_tcsflush (), term
);
468 result
= termios_tcsetattr (fd
, termios_tcsdrain (), term
);
471 term
= termios_KillTermios (term
);
474 extern "C" void _M2_IO_init (__attribute__((unused
)) int argc
, __attribute__((unused
)) char *argv
[], __attribute__((unused
)) char *envp
[])
479 extern "C" void _M2_IO_fini (__attribute__((unused
)) int argc
, __attribute__((unused
)) char *argv
[], __attribute__((unused
)) char *envp
[])