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/>. */
29 # if !defined (PROC_D)
31 typedef void (*PROC_t
) (void);
32 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)
289 fdState
.array
[0].IsEof
= false;
290 fdState
.array
[0].IsRaw
= false;
291 fdState
.array
[1].IsEof
= false;
292 fdState
.array
[1].IsRaw
= false;
293 fdState
.array
[2].IsEof
= false;
294 fdState
.array
[2].IsRaw
= false;
299 IsDefaultFd - returns TRUE if, fd, is 0, 1 or 2.
302 extern "C" void IO_Read (char *ch
)
306 FIO_FlushBuffer (FIO_StdOut
);
307 FIO_FlushBuffer (FIO_StdErr
);
308 if (fdState
.array
[0].IsRaw
)
310 if (fdState
.array
[0].IsEof
)
318 r
= static_cast<int> (libc_read (FIO_GetUnixFileDescriptor (FIO_StdIn
), ch
, static_cast<size_t> (1)));
325 /* avoid dangling else. */
326 r
= errno_geterrno ();
327 if (r
!= errno_EAGAIN
)
329 fdState
.array
[0].IsEof
= true;
339 (*ch
) = FIO_ReadChar (FIO_StdIn
);
345 doWrite - performs the write of a single character, ch,
349 extern "C" void IO_Write (char ch
)
351 doWrite (1, FIO_StdOut
, ch
);
356 doWrite - performs the write of a single character, ch,
360 extern "C" void IO_Error (char ch
)
362 doWrite (2, FIO_StdErr
, ch
);
365 extern "C" void IO_UnBufferedMode (int fd
, bool input
)
367 termios_TERMIOS term
;
370 if (IsDefaultFd (fd
))
372 fdState
.array
[fd
].IsRaw
= true;
374 term
= termios_InitTermios ();
375 if ((termios_tcgetattr (fd
, term
)) == 0)
380 result
= termios_tcsetattr (fd
, termios_tcsflush (), term
);
384 result
= termios_tcsetattr (fd
, termios_tcsdrain (), term
);
387 term
= termios_KillTermios (term
);
390 extern "C" void IO_BufferedMode (int fd
, bool input
)
392 termios_TERMIOS term
;
395 if (IsDefaultFd (fd
))
397 fdState
.array
[fd
].IsRaw
= false;
399 term
= termios_InitTermios ();
400 if ((termios_tcgetattr (fd
, term
)) == 0)
405 r
= termios_tcsetattr (fd
, termios_tcsflush (), term
);
409 r
= termios_tcsetattr (fd
, termios_tcsdrain (), term
);
412 term
= termios_KillTermios (term
);
417 EchoOn - turns on echoing for file descriptor, fd. This
418 only really makes sence for a file descriptor opened
419 for terminal input or maybe some specific file descriptor
420 which is attached to a particular piece of hardware.
423 extern "C" void IO_EchoOn (int fd
, bool input
)
425 termios_TERMIOS term
;
428 term
= termios_InitTermios ();
429 if ((termios_tcgetattr (fd
, term
)) == 0)
431 setFlag (term
, termios_lecho
, true);
434 result
= termios_tcsetattr (fd
, termios_tcsflush (), term
);
438 result
= termios_tcsetattr (fd
, termios_tcsdrain (), term
);
441 term
= termios_KillTermios (term
);
446 EchoOff - turns off echoing for file descriptor, fd. This
447 only really makes sence for a file descriptor opened
448 for terminal input or maybe some specific file descriptor
449 which is attached to a particular piece of hardware.
452 extern "C" void IO_EchoOff (int fd
, bool input
)
454 termios_TERMIOS term
;
457 term
= termios_InitTermios ();
458 if ((termios_tcgetattr (fd
, term
)) == 0)
460 setFlag (term
, termios_lecho
, false);
463 result
= termios_tcsetattr (fd
, termios_tcsflush (), term
);
467 result
= termios_tcsetattr (fd
, termios_tcsdrain (), term
);
470 term
= termios_KillTermios (term
);
473 extern "C" void _M2_IO_init (__attribute__((unused
)) int argc
,__attribute__((unused
)) char *argv
[],__attribute__((unused
)) char *envp
[])
478 extern "C" void _M2_IO_fini (__attribute__((unused
)) int argc
,__attribute__((unused
)) char *argv
[],__attribute__((unused
)) char *envp
[])