]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/m2/pge-boot/GIO.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / m2 / pge-boot / GIO.cc
1 /* do not edit automatically generated by mc from IO. */
2 /* IO.mod provides Read, Write, Errors procedures mapping onto 0, 1 and 2.
3
4 Copyright (C) 2001-2024 Free Software Foundation, Inc.
5 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
6
7 This file is part of GNU Modula-2.
8
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)
12 any later version.
13
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.
18
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.
22
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/>. */
27
28 #include <stdbool.h>
29 # if !defined (PROC_D)
30 # define PROC_D
31 typedef void (*PROC_t) (void);
32 typedef struct { PROC_t proc; } PROC;
33 # endif
34
35 # if !defined (TRUE)
36 # define TRUE (1==1)
37 # endif
38
39 # if !defined (FALSE)
40 # define FALSE (1==0)
41 # endif
42
43 #include <stdlib.h>
44 #include <unistd.h>
45 #define _IO_H
46 #define _IO_C
47
48 # include "GStrLib.h"
49 # include "GSYSTEM.h"
50 # include "Glibc.h"
51 # include "GFIO.h"
52 # include "Gerrno.h"
53 # include "GASCII.h"
54 # include "Gtermios.h"
55
56 # define MaxDefaultFd 2
57 typedef struct IO_BasicFds_r IO_BasicFds;
58
59 typedef struct IO__T1_a IO__T1;
60
61 struct IO_BasicFds_r {
62 bool IsEof;
63 bool IsRaw;
64 };
65
66 struct IO__T1_a { IO_BasicFds array[MaxDefaultFd+1]; };
67 static IO__T1 fdState;
68
69 /*
70 IsDefaultFd - returns TRUE if, fd, is 0, 1 or 2.
71 */
72
73 extern "C" void IO_Read (char *ch);
74
75 /*
76 doWrite - performs the write of a single character, ch,
77 onto fd or f.
78 */
79
80 extern "C" void IO_Write (char ch);
81
82 /*
83 doWrite - performs the write of a single character, ch,
84 onto fd or f.
85 */
86
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);
90
91 /*
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.
96 */
97
98 extern "C" void IO_EchoOn (int fd, bool input);
99
100 /*
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.
105 */
106
107 extern "C" void IO_EchoOff (int fd, bool input);
108
109 /*
110 IsDefaultFd - returns TRUE if, fd, is 0, 1 or 2.
111 */
112
113 static bool IsDefaultFd (int fd);
114
115 /*
116 doWrite - performs the write of a single character, ch,
117 onto fd or f.
118 */
119
120 static void doWrite (int fd, FIO_File f, char ch);
121
122 /*
123 setFlag - sets or unsets the appropriate flag in, t.
124 */
125
126 static void setFlag (termios_TERMIOS t, termios_Flag f, bool b);
127
128 /*
129 doraw - sets all the flags associated with making this
130 file descriptor into raw input/output.
131 */
132
133 static void doraw (termios_TERMIOS term);
134
135 /*
136 dononraw - sets all the flags associated with making this
137 file descriptor into non raw input/output.
138 */
139
140 static void dononraw (termios_TERMIOS term);
141
142 /*
143 Init -
144 */
145
146 static void Init (void);
147
148
149 /*
150 IsDefaultFd - returns TRUE if, fd, is 0, 1 or 2.
151 */
152
153 static bool IsDefaultFd (int fd)
154 {
155 return (fd <= MaxDefaultFd) && (fd >= 0);
156 /* static analysis guarentees a RETURN statement will be used before here. */
157 __builtin_unreachable ();
158 }
159
160
161 /*
162 doWrite - performs the write of a single character, ch,
163 onto fd or f.
164 */
165
166 static void doWrite (int fd, FIO_File f, char ch)
167 {
168 int r;
169
170 if (fdState.array[fd].IsRaw)
171 {
172 /* avoid dangling else. */
173 if (! fdState.array[fd].IsEof)
174 {
175 for (;;)
176 {
177 r = static_cast<int> (libc_write (FIO_GetUnixFileDescriptor (f), &ch, static_cast<size_t> (1)));
178 if (r == 1)
179 {
180 return ;
181 }
182 else if (r == -1)
183 {
184 /* avoid dangling else. */
185 r = errno_geterrno ();
186 if ((r != errno_EAGAIN) && (r != errno_EINTR))
187 {
188 fdState.array[fd].IsEof = true;
189 return ;
190 }
191 }
192 }
193 }
194 }
195 else
196 {
197 FIO_WriteChar (f, ch);
198 }
199 }
200
201
202 /*
203 setFlag - sets or unsets the appropriate flag in, t.
204 */
205
206 static void setFlag (termios_TERMIOS t, termios_Flag f, bool b)
207 {
208 if (termios_SetFlag (t, f, b))
209 {} /* empty. */
210 }
211
212
213 /*
214 doraw - sets all the flags associated with making this
215 file descriptor into raw input/output.
216 */
217
218 static void doraw (termios_TERMIOS term)
219 {
220 /*
221 * from man 3 termios
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;
228 */
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);
245 }
246
247
248 /*
249 dononraw - sets all the flags associated with making this
250 file descriptor into non raw input/output.
251 */
252
253 static void dononraw (termios_TERMIOS term)
254 {
255 /*
256 * we undo these settings, (although we leave the character size alone)
257 *
258 * from man 3 termios
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;
265 */
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);
280 }
281
282
283 /*
284 Init -
285 */
286
287 static void Init (void)
288 {
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;
295 }
296
297
298 /*
299 IsDefaultFd - returns TRUE if, fd, is 0, 1 or 2.
300 */
301
302 extern "C" void IO_Read (char *ch)
303 {
304 int r;
305
306 FIO_FlushBuffer (FIO_StdOut);
307 FIO_FlushBuffer (FIO_StdErr);
308 if (fdState.array[0].IsRaw)
309 {
310 if (fdState.array[0].IsEof)
311 {
312 (*ch) = ASCII_eof;
313 }
314 else
315 {
316 for (;;)
317 {
318 r = static_cast<int> (libc_read (FIO_GetUnixFileDescriptor (FIO_StdIn), ch, static_cast<size_t> (1)));
319 if (r == 1)
320 {
321 return ;
322 }
323 else if (r == -1)
324 {
325 /* avoid dangling else. */
326 r = errno_geterrno ();
327 if (r != errno_EAGAIN)
328 {
329 fdState.array[0].IsEof = true;
330 (*ch) = ASCII_eof;
331 return ;
332 }
333 }
334 }
335 }
336 }
337 else
338 {
339 (*ch) = FIO_ReadChar (FIO_StdIn);
340 }
341 }
342
343
344 /*
345 doWrite - performs the write of a single character, ch,
346 onto fd or f.
347 */
348
349 extern "C" void IO_Write (char ch)
350 {
351 doWrite (1, FIO_StdOut, ch);
352 }
353
354
355 /*
356 doWrite - performs the write of a single character, ch,
357 onto fd or f.
358 */
359
360 extern "C" void IO_Error (char ch)
361 {
362 doWrite (2, FIO_StdErr, ch);
363 }
364
365 extern "C" void IO_UnBufferedMode (int fd, bool input)
366 {
367 termios_TERMIOS term;
368 int result;
369
370 if (IsDefaultFd (fd))
371 {
372 fdState.array[fd].IsRaw = true;
373 }
374 term = termios_InitTermios ();
375 if ((termios_tcgetattr (fd, term)) == 0)
376 {
377 doraw (term);
378 if (input)
379 {
380 result = termios_tcsetattr (fd, termios_tcsflush (), term);
381 }
382 else
383 {
384 result = termios_tcsetattr (fd, termios_tcsdrain (), term);
385 }
386 }
387 term = termios_KillTermios (term);
388 }
389
390 extern "C" void IO_BufferedMode (int fd, bool input)
391 {
392 termios_TERMIOS term;
393 int r;
394
395 if (IsDefaultFd (fd))
396 {
397 fdState.array[fd].IsRaw = false;
398 }
399 term = termios_InitTermios ();
400 if ((termios_tcgetattr (fd, term)) == 0)
401 {
402 dononraw (term);
403 if (input)
404 {
405 r = termios_tcsetattr (fd, termios_tcsflush (), term);
406 }
407 else
408 {
409 r = termios_tcsetattr (fd, termios_tcsdrain (), term);
410 }
411 }
412 term = termios_KillTermios (term);
413 }
414
415
416 /*
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.
421 */
422
423 extern "C" void IO_EchoOn (int fd, bool input)
424 {
425 termios_TERMIOS term;
426 int result;
427
428 term = termios_InitTermios ();
429 if ((termios_tcgetattr (fd, term)) == 0)
430 {
431 setFlag (term, termios_lecho, true);
432 if (input)
433 {
434 result = termios_tcsetattr (fd, termios_tcsflush (), term);
435 }
436 else
437 {
438 result = termios_tcsetattr (fd, termios_tcsdrain (), term);
439 }
440 }
441 term = termios_KillTermios (term);
442 }
443
444
445 /*
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.
450 */
451
452 extern "C" void IO_EchoOff (int fd, bool input)
453 {
454 termios_TERMIOS term;
455 int result;
456
457 term = termios_InitTermios ();
458 if ((termios_tcgetattr (fd, term)) == 0)
459 {
460 setFlag (term, termios_lecho, false);
461 if (input)
462 {
463 result = termios_tcsetattr (fd, termios_tcsflush (), term);
464 }
465 else
466 {
467 result = termios_tcsetattr (fd, termios_tcsdrain (), term);
468 }
469 }
470 term = termios_KillTermios (term);
471 }
472
473 extern "C" void _M2_IO_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
474 {
475 Init ();
476 }
477
478 extern "C" void _M2_IO_fini (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
479 {
480 }