]> gcc.gnu.org Git - gcc.git/blame - gcc/ada/sysdep.c
3psoccon.ads, [...]: Files added.
[gcc.git] / gcc / ada / sysdep.c
CommitLineData
996ae0b0
RK
1/****************************************************************************
2 * *
3 * GNAT COMPILER COMPONENTS *
4 * *
5 * S Y S D E P *
6 * *
7 * C Implementation File *
8 * *
fbf5a39b 9 * Copyright (C) 1992-2003 Free Software Foundation, Inc. *
996ae0b0
RK
10 * *
11 * GNAT is free software; you can redistribute it and/or modify it under *
12 * terms of the GNU General Public License as published by the Free Soft- *
13 * ware Foundation; either version 2, or (at your option) any later ver- *
14 * sion. GNAT is distributed in the hope that it will be useful, but WITH- *
15 * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
17 * for more details. You should have received a copy of the GNU General *
18 * Public License distributed with GNAT; see file COPYING. If not, write *
19 * to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, *
20 * MA 02111-1307, USA. *
21 * *
22 * As a special exception, if you link this file with other files to *
23 * produce an executable, this file does not by itself cause the resulting *
24 * executable to be covered by the GNU General Public License. This except- *
25 * ion does not however invalidate any other reasons why the executable *
26 * file might be covered by the GNU Public License. *
27 * *
28 * GNAT was originally developed by the GNAT team at New York University. *
71ff80dc 29 * Extensive contributions were provided by Ada Core Technologies Inc. *
996ae0b0
RK
30 * *
31 ****************************************************************************/
32
33/* This file contains system dependent symbols that are referenced in the
34 GNAT Run Time Library */
35
36#ifdef __vxworks
07fc65c4
GB
37#include "ioLib.h"
38#include "selectLib.h"
996ae0b0
RK
39#include "vxWorks.h"
40#endif
41#ifdef IN_RTS
42#define POSIX
43#include "tconfig.h"
44#include "tsystem.h"
45#include <fcntl.h>
46#include <sys/stat.h>
47#include "time.h"
48#else
49#include "config.h"
50#include "system.h"
51#endif
52
53#include "adaint.h"
54
55/*
56 mode_read_text
57 open text file for reading
58 rt for DOS and Windows NT, r for Unix
59
60 mode_write_text
61 truncate to zero length or create text file for writing
62 wt for DOS and Windows NT, w for Unix
63
64 mode_append_text
65 append; open or create text file for writing at end-of-file
66 at for DOS and Windows NT, a for Unix
67
68 mode_read_binary
69 open binary file for reading
70 rb for DOS and Windows NT, r for Unix
71
72 mode_write_binary
73 truncate to zero length or create binary file for writing
74 wb for DOS and Windows NT, w for Unix
75
76 mode_append_binary
77 append; open or create binary file for writing at end-of-file
78 ab for DOS and Windows NT, a for Unix
79
80 mode_read_text_plus
81 open text file for update (reading and writing)
82 r+t for DOS and Windows NT, r+ for Unix
83
84 mode_write_text_plus
85 truncate to zero length or create text file for update
86 w+t for DOS and Windows NT, w+ for Unix
87
88 mode_append_text_plus
89 append; open or create text file for update, writing at end-of-file
90 a+t for DOS and Windows NT, a+ for Unix
91
92 mode_read_binary_plus
93 open binary file for update (reading and writing)
94 r+b for DOS and Windows NT, r+ for Unix
95
96 mode_write_binary_plus
97 truncate to zero length or create binary file for update
98 w+b for DOS and Windows NT, w+ for Unix
99
100 mode_append_binary_plus
101 append; open or create binary file for update, writing at end-of-file
102 a+b for DOS and Windows NT, a+ for Unix
103
104 Notes:
105
106 (1) Opening a file with read mode fails if the file does not exist or
107 cannot be read.
108
109 (2) Opening a file with append mode causes all subsequent writes to the
110 file to be forced to the then current end-of-file, regardless of
111 intervening calls to the fseek function.
112
113 (3) When a file is opened with update mode, both input and output may be
114 performed on the associated stream. However, output may not be directly
115 followed by input without an intervening call to the fflush function or
116 to a file positioning function (fseek, fsetpos, or rewind), and input
117 may not be directly followed by output without an intervening call to a
118 file positioning function, unless the input operation encounters
119 end-of-file.
120
121 The other target dependent declarations here are for the two functions
122 __gnat_set_binary_mode and __gnat_set_text_mode:
123
124 void __gnat_set_binary_mode (int handle);
125 void __gnat_set_text_mode (int handle);
126
127 These functions have no effect in Unix (or similar systems where there is
128 no distinction between binary and text files), but in DOS (and similar
129 systems where text mode does CR/LF translation), these functions allow
130 the mode of the stream with the given handle (fileno can be used to get
131 the handle of a stream) to be changed dynamically. The returned result
132 is 0 if no error occurs and -1 if an error occurs.
133
134 Finally there is a boolean (character) variable
135
136 char __gnat_text_translation_required;
137
138 which is zero (false) in Unix mode, and one (true) in DOS mode, with a
139 true value indicating that text translation is required on text files
140 and that fopen supports the trailing t and b modifiers.
141
142*/
143
144#if defined(WINNT) || defined (MSDOS) || defined (__EMX__)
07fc65c4
GB
145static const char *mode_read_text = "rt";
146static const char *mode_write_text = "wt";
147static const char *mode_append_text = "at";
148static const char *mode_read_binary = "rb";
149static const char *mode_write_binary = "wb";
150static const char *mode_append_binary = "ab";
151static const char *mode_read_text_plus = "r+t";
152static const char *mode_write_text_plus = "w+t";
153static const char *mode_append_text_plus = "a+t";
154static const char *mode_read_binary_plus = "r+b";
155static const char *mode_write_binary_plus = "w+b";
156static const char *mode_append_binary_plus = "a+b";
996ae0b0
RK
157const char __gnat_text_translation_required = 1;
158
159void
160__gnat_set_binary_mode (handle)
161 int handle;
162{
163 _setmode (handle, O_BINARY);
164}
165
166void
167__gnat_set_text_mode (handle)
168 int handle;
169{
170 _setmode (handle, O_TEXT);
171}
172
173#ifdef __MINGW32__
174#include <windows.h>
175
176/* Return the name of the tty. Under windows there is no name for
177 the tty, so this function, if connected to a tty, returns the generic name
178 "console". */
179
180char *
181__gnat_ttyname (filedes)
182 int filedes;
183{
184 if (isatty (filedes))
185 return "console";
186 else
187 return NULL;
188}
189
190/* This function is needed to fix a bug under Win95/98. Under these plateforms
191 doing :
192 ch1 = getch();
193 ch2 = fgetc (stdin);
194
195 will put the same character into ch1 and ch2. It seem that the character
196 read by getch() is not correctly removed from the buffer. Even a
197 fflush(stdin) does not fix the bug. This bug does not appear under Window
198 NT. So we have two version of this routine below one for 95/98 and one for
199 NT/2000 version of Windows. There is also a special routine (winflushinit)
200 that will be called only the first time to check which version of Windows
201 we are running running on to set the right routine to use.
202
203 This problem occurs when using Text_IO.Get_Line after Text_IO.Get_Immediate
204 for example.
205
fbf5a39b 206 Calling FlushConsoleInputBuffer just after getch() fix the bug under
996ae0b0
RK
207 95/98. */
208
209static void winflush_init PARAMS ((void));
210
211static void winflush_95 PARAMS ((void));
212
213static void winflush_nt PARAMS ((void));
214
215/* winflusfunction is set first to the winflushinit function which will check
216 the OS version 95/98 or NT/2000 */
217
218static void (*winflush_function) PARAMS ((void)) = winflush_init;
219
220/* This function does the runtime check of the OS version and then sets
fbf5a39b 221 winflush_function to the appropriate function and then call it. */
996ae0b0
RK
222
223static void
224winflush_init ()
fbf5a39b 225{
996ae0b0
RK
226 DWORD dwVersion = GetVersion();
227
228 if (dwVersion < 0x80000000) /* Windows NT/2000 */
229 winflush_function = winflush_nt;
230 else /* Windows 95/98 */
231 winflush_function = winflush_95;
232
233 (*winflush_function)(); /* Perform the 'flush' */
234
235}
236
237static void winflush_95 ()
fbf5a39b 238{
996ae0b0
RK
239 FlushConsoleInputBuffer (GetStdHandle (STD_INPUT_HANDLE));
240}
241
242static void winflush_nt ()
243{
244 /* Does nothing as there is no problem under NT. */
245}
246#endif
247
248#else
249
07fc65c4
GB
250static const char *mode_read_text = "r";
251static const char *mode_write_text = "w";
252static const char *mode_append_text = "a";
253static const char *mode_read_binary = "r";
254static const char *mode_write_binary = "w";
255static const char *mode_append_binary = "a";
256static const char *mode_read_text_plus = "r+";
257static const char *mode_write_text_plus = "w+";
258static const char *mode_append_text_plus = "a+";
259static const char *mode_read_binary_plus = "r+";
260static const char *mode_write_binary_plus = "w+";
261static const char *mode_append_binary_plus = "a+";
996ae0b0
RK
262const char __gnat_text_translation_required = 0;
263
264/* These functions do nothing in non-DOS systems. */
265
266void
7f50e2e3
GB
267__gnat_set_binary_mode (handle)
268 int handle ATTRIBUTE_UNUSED;
996ae0b0
RK
269{
270}
271
272void
7f50e2e3
GB
273__gnat_set_text_mode (handle)
274 int handle ATTRIBUTE_UNUSED;
996ae0b0
RK
275{
276}
277char *
278__gnat_ttyname (filedes)
279 int filedes;
280{
281#ifndef __vxworks
282 extern char *ttyname PARAMS ((int));
283
284 return ttyname (filedes);
285
286#else
287 return "";
288
289#endif
290}
291#endif
292\f
293#if defined (linux) || defined (sun) || defined (sgi) || defined (__EMX__) \
294 || (defined (__osf__) && ! defined (__alpha_vxworks)) || defined (WINNT) \
07fc65c4 295 || defined (__MACHTEN__) || defined (hpux) || defined (_AIX) \
fbf5a39b
AC
296 || (defined (__svr4__) && defined (i386)) || defined (__Lynx__)
297
298#ifdef __MINGW32__
299#if OLD_MINGW
996ae0b0 300#include <termios.h>
fbf5a39b
AC
301#endif
302#else
303#include <termios.h>
304#endif
996ae0b0 305
45659035
GB
306#else
307#if defined (VMS)
996ae0b0
RK
308extern char *decc$ga_stdscr;
309static int initted = 0;
310#endif
45659035 311#endif
996ae0b0
RK
312
313/* Implements the common processing for getc_immediate and
314 getc_immediate_nowait. */
315
316extern void getc_immediate PARAMS ((FILE *, int *, int *));
317extern void getc_immediate_nowait PARAMS ((FILE *, int *, int *, int *));
318extern void getc_immediate_common PARAMS ((FILE *, int *, int *,
319 int *, int));
320
321/* Called by Get_Immediate (Foo); */
322
323void
324getc_immediate (stream, ch, end_of_file)
325 FILE *stream;
326 int *ch;
327 int *end_of_file;
328{
329 int avail;
330
331 getc_immediate_common (stream, ch, end_of_file, &avail, 1);
332}
333
334/* Called by Get_Immediate (Foo, Available); */
335
336void
337getc_immediate_nowait (stream, ch, end_of_file, avail)
338 FILE *stream;
339 int *ch;
340 int *end_of_file;
341 int *avail;
342{
343 getc_immediate_common (stream, ch, end_of_file, avail, 0);
344}
345
346/* Called by getc_immediate () and getc_immediate_nowait () */
347
348void
349getc_immediate_common (stream, ch, end_of_file, avail, waiting)
350 FILE *stream;
351 int *ch;
352 int *end_of_file;
353 int *avail;
354 int waiting;
355{
356#if defined (linux) || defined (sun) || defined (sgi) || defined (__EMX__) \
357 || (defined (__osf__) && ! defined (__alpha_vxworks)) \
fbf5a39b 358 || defined (__CYGWIN32__) || defined (__MACHTEN__) || defined (hpux) \
07fc65c4
GB
359 || defined (_AIX) || (defined (__svr4__) && defined (i386)) \
360 || defined (__Lynx__)
996ae0b0
RK
361 char c;
362 int nread;
363 int good_one = 0;
364 int eof_ch = 4; /* Ctrl-D */
365 int fd = fileno (stream);
366 struct termios otermios_rec, termios_rec;
367
368 if (isatty (fd))
369 {
370 tcgetattr (fd, &termios_rec);
371 memcpy (&otermios_rec, &termios_rec, sizeof (struct termios));
07fc65c4
GB
372
373 /* Set RAW mode, with no echo */
374 termios_rec.c_lflag = termios_rec.c_lflag & ~ICANON & ~ECHO;
375
376#if defined(linux) || defined (sun) || defined (sgi) || defined (__EMX__) \
377 || defined (__osf__) || defined (__MACHTEN__) || defined (hpux) \
378 || defined (_AIX) || (defined (__svr4__) && defined (i386)) \
379 || defined (__Lynx__)
380 eof_ch = termios_rec.c_cc[VEOF];
381
382 /* If waiting (i.e. Get_Immediate (Char)), set MIN = 1 and wait for
383 a character forever. This doesn't seem to effect Ctrl-Z or
384 Ctrl-C processing except on OS/2 where Ctrl-C won't work right
385 unless we do a read loop. Luckily we can delay a bit between
386 iterations. If not waiting (i.e. Get_Immediate (Char, Available)),
387 don't wait for anything but timeout immediately. */
996ae0b0 388#ifdef __EMX__
07fc65c4
GB
389 termios_rec.c_cc[VMIN] = 0;
390 termios_rec.c_cc[VTIME] = waiting;
996ae0b0 391#else
07fc65c4
GB
392 termios_rec.c_cc[VMIN] = waiting;
393 termios_rec.c_cc[VTIME] = 0;
996ae0b0
RK
394#endif
395#endif
07fc65c4 396 tcsetattr (fd, TCSANOW, &termios_rec);
996ae0b0 397
07fc65c4
GB
398 while (! good_one)
399 {
400 /* Read is used here instead of fread, because fread doesn't
996ae0b0
RK
401 work on Solaris5 and Sunos4 in this situation. Maybe because we
402 are mixing calls that use file descriptors and streams. */
996ae0b0
RK
403 nread = read (fd, &c, 1);
404 if (nread > 0)
405 {
406 /* On Unix terminals, Ctrl-D (EOT) is an End of File. */
407 if (c == eof_ch)
408 {
409 *avail = 0;
410 *end_of_file = 1;
411 good_one = 1;
412 }
413
414 /* Everything else is ok */
415 else if (c != eof_ch)
416 {
417 *avail = 1;
418 *end_of_file = 0;
419 good_one = 1;
420 }
421 }
422
423 else if (! waiting)
424 {
425 *avail = 0;
426 *end_of_file = 0;
427 good_one = 1;
428 }
429 else
07fc65c4 430 good_one = 0;
996ae0b0
RK
431 }
432
433 tcsetattr (fd, TCSANOW, &otermios_rec);
434 *ch = c;
435 }
436
437 else
07fc65c4 438#elif defined (VMS)
996ae0b0
RK
439 int fd = fileno (stream);
440
441 if (isatty (fd))
442 {
443 if (initted == 0)
444 {
445 decc$bsd_initscr ();
446 initted = 1;
447 }
07fc65c4 448
996ae0b0
RK
449 decc$bsd_cbreak ();
450 *ch = decc$bsd_wgetch (decc$ga_stdscr);
451
452 if (*ch == 4)
453 *end_of_file = 1;
454 else
455 *end_of_file = 0;
456
457 *avail = 1;
458 decc$bsd_nocbreak ();
459 }
460 else
07fc65c4 461#elif defined (__MINGW32__)
996ae0b0
RK
462 int fd = fileno (stream);
463 int char_waiting;
464 int eot_ch = 4; /* Ctrl-D */
465
466 if (isatty (fd))
467 {
468 if (waiting)
469 {
07fc65c4
GB
470 *ch = getch ();
471 (*winflush_function) ();
996ae0b0
RK
472
473 if (*ch == eot_ch)
474 *end_of_file = 1;
475 else
476 *end_of_file = 0;
477
478 *avail = 1;
479 }
480 else /* ! waiting */
481 {
482 char_waiting = kbhit();
483
484 if (char_waiting == 1)
485 {
486 *avail = 1;
07fc65c4
GB
487 *ch = getch ();
488 (*winflush_function) ();
996ae0b0
RK
489
490 if (*ch == eot_ch)
491 *end_of_file = 1;
492 else
493 *end_of_file = 0;
494 }
495 else
496 {
497 *avail = 0;
498 *end_of_file = 0;
499 }
500 }
501 }
502 else
07fc65c4
GB
503#elif defined (__vxworks)
504 /* Bit masks of file descriptors to read from. */
505 struct fd_set readFds;
fbf5a39b 506 /* Timeout before select returns if nothing can be read. */
07fc65c4
GB
507 struct timeval timeOut;
508 char c;
509 int fd = fileno (stream);
510 int nread;
511 int option;
512 int readable;
513 int status;
514 int width;
515
fbf5a39b 516 if (isatty (fd))
07fc65c4
GB
517 {
518 /* If we do not want to wait, we have to set up fd in RAW mode. This
519 should be done outside this function as setting fd in RAW mode under
520 vxWorks flushes the buffer of fd. If the RAW mode was set here, the
521 buffer would be empty and we would always return that no character
522 is available */
fbf5a39b 523 if (! waiting)
07fc65c4
GB
524 {
525 /* Initialization of timeOut for its use with select. */
526 timeOut.tv_sec = 0;
527 timeOut.tv_usec = 0;
528
529 /* Initialization of readFds for its use with select;
530 FD is the only file descriptor to be monitored */
531 FD_ZERO (&readFds);
532 FD_SET (fd, &readFds);
533 width = 2;
534
535 /* We do all this processing to emulate a non blocking read. */
536 readable = select (width, &readFds, NULL, NULL, &timeOut);
537 if (readable == ERROR)
538 *avail = -1, *end_of_file = -1;
539 /* No character available in input. */
540 else if (readable == 0)
541 *avail = 0, *end_of_file = 0;
542 else
543 {
544 nread = read (fd, &c, 1);
fbf5a39b 545 if (nread > 0)
07fc65c4
GB
546 *avail = 1, *end_of_file = 0;
547 /* End Of File. */
fbf5a39b 548 else if (nread == 0)
07fc65c4
GB
549 *avail = 0, *end_of_file = 1;
550 /* Error. */
fbf5a39b 551 else
07fc65c4 552 *avail = -1, *end_of_file = -1;
fbf5a39b 553 }
07fc65c4
GB
554 }
555
556 /* We have to wait until we get a character */
fbf5a39b 557 else
07fc65c4
GB
558 {
559 *avail = -1;
560 *end_of_file = -1;
561
562 /* Save the current mode of FD. */
563 option = ioctl (fd, FIOGETOPTIONS, 0);
564
565 /* Set FD in RAW mode. */
566 status = ioctl (fd, FIOSETOPTIONS, OPT_RAW);
fbf5a39b 567 if (status != -1)
07fc65c4
GB
568 {
569 nread = read (fd, &c, 1);
fbf5a39b 570 if (nread > 0)
07fc65c4
GB
571 *avail = 1, *end_of_file = 0;
572 /* End of file. */
fbf5a39b 573 else if (nread == 0)
07fc65c4
GB
574 *avail = 0, *end_of_file = 1;
575 /* Else there is an ERROR. */
576 }
577
578 /* Revert FD to its previous mode. */
579 status = ioctl (fd, FIOSETOPTIONS, option);
580 }
581
582 *ch = c;
583 }
584 else
996ae0b0
RK
585#endif
586 {
587 /* If we're not on a terminal, then we don't need any fancy processing.
588 Also this is the only thing that's left if we're not on one of the
07fc65c4
GB
589 supported systems; which means that for non supported systems,
590 get_immediate may wait for a carriage return on terminals. */
996ae0b0
RK
591 *ch = fgetc (stream);
592 if (feof (stream))
593 {
594 *end_of_file = 1;
595 *avail = 0;
596 }
597 else
598 {
599 *end_of_file = 0;
600 *avail = 1;
601 }
602 }
603}
604
605/* The following definitions are provided in NT to support Windows based
606 Ada programs. */
607
608#ifdef WINNT
609#include <windows.h>
610
611/* Provide functions to echo the values passed to WinMain (windows bindings
612 will want to import these). We use the same names as the routines used
613 by AdaMagic for compatibility. */
614
b0df4321
LG
615char *rts_get_hInstance PARAMS ((void));
616char *rts_get_hPrevInstance PARAMS ((void));
617char *rts_get_lpCommandLine PARAMS ((void));
618int rts_get_nShowCmd PARAMS ((void));
619
92fa4733 620char *
fbf5a39b
AC
621rts_get_hInstance ()
622{
623 return (char *)GetModuleHandleA (0);
92fa4733
LG
624}
625
626char *
fbf5a39b
AC
627rts_get_hPrevInstance ()
628{
629 return 0;
92fa4733
LG
630}
631
632char *
fbf5a39b
AC
633rts_get_lpCommandLine ()
634{
635 return GetCommandLineA ();
92fa4733
LG
636}
637
fbf5a39b
AC
638int
639rts_get_nShowCmd ()
640{
641 return 1;
92fa4733 642}
996ae0b0
RK
643
644#endif /* WINNT */
645#ifdef VMS
646
647/* This gets around a problem with using the old threads library on VMS 7.0. */
648
649#include <time.h>
650
651extern long get_gmtoff PARAMS ((void));
652
653long
654get_gmtoff ()
655{
656 time_t t;
657 struct tm *ts;
658
659 t = time ((time_t) 0);
660 ts = localtime (&t);
661 return ts->tm_gmtoff;
662}
663#endif
664
665/* Definition of __gnat_locatime_r used by a-calend.adb */
666
667#if defined (_AIX) || defined (__EMX__)
668#define Lock_Task system__soft_links__lock_task
b0df4321 669extern void (*Lock_Task) PARAMS ((void));
996ae0b0
RK
670
671#define Unlock_Task system__soft_links__unlock_task
b0df4321 672extern void (*Unlock_Task) PARAMS ((void));
996ae0b0
RK
673
674/* Provide reentrant version of localtime on Aix and OS/2. Note that AiX does
675 provide localtime_r, but in the library libc_r which doesn't get included
676 systematically, so we can't use it. */
677
fbf5a39b
AC
678extern struct tm *__gnat_localtime_r PARAMS ((const time_t *,
679 struct tm *));
996ae0b0
RK
680
681struct tm *
682__gnat_localtime_r (timer, tp)
683 const time_t *timer;
684 struct tm *tp;
685{
686 struct tm *tmp;
687
688 (*Lock_Task) ();
689 tmp = localtime (timer);
690 memcpy (tp, tmp, sizeof (struct tm));
691 (*Unlock_Task) ();
692 return tp;
693}
694
45659035
GB
695#else
696#if defined (__Lynx__) && defined (___THREADS_POSIX4ad4__)
996ae0b0 697
45659035
GB
698/* As of LynxOS 3.1.0a patch level 040, LynuxWorks changes the
699 prototype to the C library function localtime_r from the POSIX.4
700 Draft 9 to the POSIX 1.c version. Before this change the following
701 spec is required. Only use when ___THREADS_POSIX4ad4__ is defined,
702 the Lynx convention when building against the legacy API. */
996ae0b0
RK
703
704extern struct tm *__gnat_localtime_r PARAMS ((const time_t *, struct tm *));
705
706struct tm *
707__gnat_localtime_r (timer, tp)
708 const time_t *timer;
709 struct tm *tp;
710{
45659035
GB
711 localtime_r (tp, timer);
712 return NULL;
996ae0b0
RK
713}
714
45659035
GB
715#else
716#if defined (VMS) || defined (__MINGW32__)
996ae0b0
RK
717
718/* __gnat_localtime_r is not needed on NT and VMS */
719
720#else
721
722/* All other targets provide a standard localtime_r */
723
724extern struct tm *__gnat_localtime_r PARAMS ((const time_t *, struct tm *));
725
726struct tm *
727__gnat_localtime_r (timer, tp)
728 const time_t *timer;
729 struct tm *tp;
730{
731 return (struct tm *) localtime_r (timer, tp);
732}
733#endif
45659035
GB
734#endif
735#endif
This page took 0.495863 seconds and 5 git commands to generate.