1 /****************************************************************************
3 * GNAT COMPILER COMPONENTS *
7 * C Implementation File *
11 * Copyright (C) 1992-2001 Free Software Foundation, Inc. *
13 * GNAT is free software; you can redistribute it and/or modify it under *
14 * terms of the GNU General Public License as published by the Free Soft- *
15 * ware Foundation; either version 2, or (at your option) any later ver- *
16 * sion. GNAT is distributed in the hope that it will be useful, but WITH- *
17 * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
18 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
19 * for more details. You should have received a copy of the GNU General *
20 * Public License distributed with GNAT; see file COPYING. If not, write *
21 * to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, *
22 * MA 02111-1307, USA. *
24 * As a special exception, if you link this file with other files to *
25 * produce an executable, this file does not by itself cause the resulting *
26 * executable to be covered by the GNU General Public License. This except- *
27 * ion does not however invalidate any other reasons why the executable *
28 * file might be covered by the GNU Public License. *
30 * GNAT was originally developed by the GNAT team at New York University. *
31 * It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). *
33 ****************************************************************************/
35 /* This file contains system dependent symbols that are referenced in the
36 GNAT Run Time Library */
57 open text file for reading
58 rt for DOS and Windows NT, r for Unix
61 truncate to zero length or create text file for writing
62 wt for DOS and Windows NT, w for Unix
65 append; open or create text file for writing at end-of-file
66 at for DOS and Windows NT, a for Unix
69 open binary file for reading
70 rb for DOS and Windows NT, r for Unix
73 truncate to zero length or create binary file for writing
74 wb for DOS and Windows NT, w for Unix
77 append; open or create binary file for writing at end-of-file
78 ab for DOS and Windows NT, a for Unix
81 open text file for update (reading and writing)
82 r+t for DOS and Windows NT, r+ for Unix
85 truncate to zero length or create text file for update
86 w+t for DOS and Windows NT, w+ for Unix
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
93 open binary file for update (reading and writing)
94 r+b for DOS and Windows NT, r+ for Unix
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
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
106 (1) Opening a file with read mode fails if the file does not exist or
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.
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
121 The other target dependent declarations here are for the two functions
122 __gnat_set_binary_mode and __gnat_set_text_mode:
124 void __gnat_set_binary_mode (int handle);
125 void __gnat_set_text_mode (int handle);
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.
134 Finally there is a boolean (character) variable
136 char __gnat_text_translation_required;
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.
144 #if defined(WINNT) || defined (MSDOS) || defined (__EMX__)
145 const char *mode_read_text = "rt";
146 const char *mode_write_text = "wt";
147 const char *mode_append_text = "at";
148 const char *mode_read_binary = "rb";
149 const char *mode_write_binary = "wb";
150 const char *mode_append_binary = "ab";
151 const char *mode_read_text_plus = "r+t";
152 const char *mode_write_text_plus = "w+t";
153 const char *mode_append_text_plus = "a+t";
154 const char *mode_read_binary_plus = "r+b";
155 const char *mode_write_binary_plus = "w+b";
156 const char *mode_append_binary_plus = "a+b";
157 const char __gnat_text_translation_required = 1;
160 __gnat_set_binary_mode (handle)
163 _setmode (handle, O_BINARY);
167 __gnat_set_text_mode (handle)
170 _setmode (handle, O_TEXT);
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
181 __gnat_ttyname (filedes)
184 if (isatty (filedes))
190 /* This function is needed to fix a bug under Win95/98. Under these plateforms
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.
203 This problem occurs when using Text_IO.Get_Line after Text_IO.Get_Immediate
206 Calling FlushConsoleInputBuffer just after getch() fix the bug under
209 static void winflush_init PARAMS ((void));
211 static void winflush_95 PARAMS ((void));
213 static void winflush_nt PARAMS ((void));
215 /* winflusfunction is set first to the winflushinit function which will check
216 the OS version 95/98 or NT/2000 */
218 static void (*winflush_function) PARAMS ((void)) = winflush_init;
220 /* This function does the runtime check of the OS version and then sets
221 winflush_function to the appropriate function and then call it. */
226 DWORD dwVersion = GetVersion();
228 if (dwVersion < 0x80000000) /* Windows NT/2000 */
229 winflush_function = winflush_nt;
230 else /* Windows 95/98 */
231 winflush_function = winflush_95;
233 (*winflush_function)(); /* Perform the 'flush' */
237 static void winflush_95 ()
239 FlushConsoleInputBuffer (GetStdHandle (STD_INPUT_HANDLE));
242 static void winflush_nt ()
244 /* Does nothing as there is no problem under NT. */
250 const char *mode_read_text = "r";
251 const char *mode_write_text = "w";
252 const char *mode_append_text = "a";
253 const char *mode_read_binary = "r";
254 const char *mode_write_binary = "w";
255 const char *mode_append_binary = "a";
256 const char *mode_read_text_plus = "r+";
257 const char *mode_write_text_plus = "w+";
258 const char *mode_append_text_plus = "a+";
259 const char *mode_read_binary_plus = "r+";
260 const char *mode_write_binary_plus = "w+";
261 const char *mode_append_binary_plus = "a+";
262 const char __gnat_text_translation_required = 0;
264 /* These functions do nothing in non-DOS systems. */
267 __gnat_set_binary_mode (handle)
268 int handle ATTRIBUTE_UNUSED;
273 __gnat_set_text_mode (handle)
274 int handle ATTRIBUTE_UNUSED;
278 __gnat_ttyname (filedes)
282 extern char *ttyname PARAMS ((int));
284 return ttyname (filedes);
293 #if defined (linux) || defined (sun) || defined (sgi) || defined (__EMX__) \
294 || (defined (__osf__) && ! defined (__alpha_vxworks)) || defined (WINNT) \
295 || defined (__MACHTEN__)
300 extern char *decc$ga_stdscr;
301 static int initted = 0;
305 /* Implements the common processing for getc_immediate and
306 getc_immediate_nowait. */
308 extern void getc_immediate PARAMS ((FILE *, int *, int *));
309 extern void getc_immediate_nowait PARAMS ((FILE *, int *, int *, int *));
310 extern void getc_immediate_common PARAMS ((FILE *, int *, int *,
313 /* Called by Get_Immediate (Foo); */
316 getc_immediate (stream, ch, end_of_file)
323 getc_immediate_common (stream, ch, end_of_file, &avail, 1);
326 /* Called by Get_Immediate (Foo, Available); */
329 getc_immediate_nowait (stream, ch, end_of_file, avail)
335 getc_immediate_common (stream, ch, end_of_file, avail, 0);
338 /* Called by getc_immediate () and getc_immediate_nowait () */
341 getc_immediate_common (stream, ch, end_of_file, avail, waiting)
348 #if defined (linux) || defined (sun) || defined (sgi) || defined (__EMX__) \
349 || (defined (__osf__) && ! defined (__alpha_vxworks)) \
350 || defined (__CYGWIN32__) || defined (__MACHTEN__)
354 int eof_ch = 4; /* Ctrl-D */
355 int fd = fileno (stream);
356 struct termios otermios_rec, termios_rec;
360 tcgetattr (fd, &termios_rec);
361 memcpy (&otermios_rec, &termios_rec, sizeof (struct termios));
365 termios_rec.c_lflag = termios_rec.c_lflag & ~ICANON;
366 #if defined(sgi) || defined (sun) || defined (__EMX__) || defined (__osf__) \
367 || defined (linux) || defined (__MACHTEN__)
368 eof_ch = termios_rec.c_cc[VEOF];
370 /* If waiting (i.e. Get_Immediate (Char)), set MIN = 1 and wait for
371 a character forever. This doesn't seem to effect Ctrl-Z or
372 Ctrl-C processing except on OS/2 where Ctrl-C won't work right
373 unless we do a read loop. Luckily we can delay a bit between
374 iterations. If not waiting (i.e. Get_Immediate (Char, Available)),
375 don't wait for anything but timeout immediately. */
377 termios_rec.c_cc[VMIN] = 0;
378 termios_rec.c_cc[VTIME] = waiting;
380 termios_rec.c_cc[VMIN] = waiting;
381 termios_rec.c_cc[VTIME] = 0;
384 tcsetattr (fd, TCSANOW, &termios_rec);
386 /* Read() is used here instead of fread(), because fread() doesn't
387 work on Solaris5 and Sunos4 in this situation. Maybe because we
388 are mixing calls that use file descriptors and streams. */
390 nread = read (fd, &c, 1);
393 /* On Unix terminals, Ctrl-D (EOT) is an End of File. */
401 /* Everything else is ok */
402 else if (c != eof_ch)
422 tcsetattr (fd, TCSANOW, &otermios_rec);
429 int fd = fileno (stream);
439 *ch = decc$bsd_wgetch (decc$ga_stdscr);
447 decc$bsd_nocbreak ();
451 #if defined (__MINGW32__)
452 int fd = fileno (stream);
454 int eot_ch = 4; /* Ctrl-D */
461 (*winflush_function)();
472 char_waiting = kbhit();
474 if (char_waiting == 1)
478 (*winflush_function)();
497 /* If we're not on a terminal, then we don't need any fancy processing.
498 Also this is the only thing that's left if we're not on one of the
499 supported systems. */
500 *ch = fgetc (stream);
514 /* The following definitions are provided in NT to support Windows based
520 /* Provide functions to echo the values passed to WinMain (windows bindings
521 will want to import these). We use the same names as the routines used
522 by AdaMagic for compatibility. */
524 char *rts_get_hInstance PARAMS ((void));
525 char *rts_get_hPrevInstance PARAMS ((void));
526 char *rts_get_lpCommandLine PARAMS ((void));
527 int rts_get_nShowCmd PARAMS ((void));
532 return GetModuleHandleA (0);
536 rts_get_hPrevInstance ()
542 rts_get_lpCommandLine ()
544 return GetCommandLineA ();
556 /* This gets around a problem with using the old threads library on VMS 7.0. */
560 extern long get_gmtoff PARAMS ((void));
568 t = time ((time_t) 0);
570 return ts->tm_gmtoff;
574 /* Definition of __gnat_locatime_r used by a-calend.adb */
576 #if defined (_AIX) || defined (__EMX__)
577 #define Lock_Task system__soft_links__lock_task
578 extern void (*Lock_Task) PARAMS ((void));
580 #define Unlock_Task system__soft_links__unlock_task
581 extern void (*Unlock_Task) PARAMS ((void));
583 /* Provide reentrant version of localtime on Aix and OS/2. Note that AiX does
584 provide localtime_r, but in the library libc_r which doesn't get included
585 systematically, so we can't use it. */
587 exrern void struct tm *__gnat_localtime_r PARAMS ((const time_t *,
591 __gnat_localtime_r (timer, tp)
598 tmp = localtime (timer);
599 memcpy (tp, tmp, sizeof (struct tm));
605 #if defined (__Lynx__) && defined (___THREADS_POSIX4ad4__)
607 /* As of LynxOS 3.1.0a patch level 040, LynuxWorks changes the
608 prototype to the C library function localtime_r from the POSIX.4
609 Draft 9 to the POSIX 1.c version. Before this change the following
610 spec is required. Only use when ___THREADS_POSIX4ad4__ is defined,
611 the Lynx convention when building against the legacy API. */
613 extern struct tm *__gnat_localtime_r PARAMS ((const time_t *, struct tm *));
616 __gnat_localtime_r (timer, tp)
620 localtime_r (tp, timer);
625 #if defined (VMS) || defined (__MINGW32__)
627 /* __gnat_localtime_r is not needed on NT and VMS */
631 /* All other targets provide a standard localtime_r */
633 extern struct tm *__gnat_localtime_r PARAMS ((const time_t *, struct tm *));
636 __gnat_localtime_r (timer, tp)
640 return (struct tm *) localtime_r (timer, tp);