]>
Commit | Line | Data |
---|---|---|
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 |
145 | static const char *mode_read_text = "rt"; |
146 | static const char *mode_write_text = "wt"; | |
147 | static const char *mode_append_text = "at"; | |
148 | static const char *mode_read_binary = "rb"; | |
149 | static const char *mode_write_binary = "wb"; | |
150 | static const char *mode_append_binary = "ab"; | |
151 | static const char *mode_read_text_plus = "r+t"; | |
152 | static const char *mode_write_text_plus = "w+t"; | |
153 | static const char *mode_append_text_plus = "a+t"; | |
154 | static const char *mode_read_binary_plus = "r+b"; | |
155 | static const char *mode_write_binary_plus = "w+b"; | |
156 | static const char *mode_append_binary_plus = "a+b"; | |
996ae0b0 RK |
157 | const char __gnat_text_translation_required = 1; |
158 | ||
159 | void | |
160 | __gnat_set_binary_mode (handle) | |
161 | int handle; | |
162 | { | |
163 | _setmode (handle, O_BINARY); | |
164 | } | |
165 | ||
166 | void | |
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 | ||
180 | char * | |
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 | ||
209 | static void winflush_init PARAMS ((void)); | |
210 | ||
211 | static void winflush_95 PARAMS ((void)); | |
212 | ||
213 | static 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 | ||
218 | static 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 | |
223 | static void | |
224 | winflush_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 | ||
237 | static void winflush_95 () | |
fbf5a39b | 238 | { |
996ae0b0 RK |
239 | FlushConsoleInputBuffer (GetStdHandle (STD_INPUT_HANDLE)); |
240 | } | |
241 | ||
242 | static void winflush_nt () | |
243 | { | |
244 | /* Does nothing as there is no problem under NT. */ | |
245 | } | |
246 | #endif | |
247 | ||
248 | #else | |
249 | ||
07fc65c4 GB |
250 | static const char *mode_read_text = "r"; |
251 | static const char *mode_write_text = "w"; | |
252 | static const char *mode_append_text = "a"; | |
253 | static const char *mode_read_binary = "r"; | |
254 | static const char *mode_write_binary = "w"; | |
255 | static const char *mode_append_binary = "a"; | |
256 | static const char *mode_read_text_plus = "r+"; | |
257 | static const char *mode_write_text_plus = "w+"; | |
258 | static const char *mode_append_text_plus = "a+"; | |
259 | static const char *mode_read_binary_plus = "r+"; | |
260 | static const char *mode_write_binary_plus = "w+"; | |
261 | static const char *mode_append_binary_plus = "a+"; | |
996ae0b0 RK |
262 | const char __gnat_text_translation_required = 0; |
263 | ||
264 | /* These functions do nothing in non-DOS systems. */ | |
265 | ||
266 | void | |
7f50e2e3 GB |
267 | __gnat_set_binary_mode (handle) |
268 | int handle ATTRIBUTE_UNUSED; | |
996ae0b0 RK |
269 | { |
270 | } | |
271 | ||
272 | void | |
7f50e2e3 GB |
273 | __gnat_set_text_mode (handle) |
274 | int handle ATTRIBUTE_UNUSED; | |
996ae0b0 RK |
275 | { |
276 | } | |
277 | char * | |
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 |
308 | extern char *decc$ga_stdscr; |
309 | static 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 | ||
316 | extern void getc_immediate PARAMS ((FILE *, int *, int *)); | |
317 | extern void getc_immediate_nowait PARAMS ((FILE *, int *, int *, int *)); | |
318 | extern void getc_immediate_common PARAMS ((FILE *, int *, int *, | |
319 | int *, int)); | |
320 | ||
321 | /* Called by Get_Immediate (Foo); */ | |
322 | ||
323 | void | |
324 | getc_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 | ||
336 | void | |
337 | getc_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 | ||
348 | void | |
349 | getc_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 |
615 | char *rts_get_hInstance PARAMS ((void)); |
616 | char *rts_get_hPrevInstance PARAMS ((void)); | |
617 | char *rts_get_lpCommandLine PARAMS ((void)); | |
618 | int rts_get_nShowCmd PARAMS ((void)); | |
619 | ||
92fa4733 | 620 | char * |
fbf5a39b AC |
621 | rts_get_hInstance () |
622 | { | |
623 | return (char *)GetModuleHandleA (0); | |
92fa4733 LG |
624 | } |
625 | ||
626 | char * | |
fbf5a39b AC |
627 | rts_get_hPrevInstance () |
628 | { | |
629 | return 0; | |
92fa4733 LG |
630 | } |
631 | ||
632 | char * | |
fbf5a39b AC |
633 | rts_get_lpCommandLine () |
634 | { | |
635 | return GetCommandLineA (); | |
92fa4733 LG |
636 | } |
637 | ||
fbf5a39b AC |
638 | int |
639 | rts_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 | ||
651 | extern long get_gmtoff PARAMS ((void)); | |
652 | ||
653 | long | |
654 | get_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 | 669 | extern void (*Lock_Task) PARAMS ((void)); |
996ae0b0 RK |
670 | |
671 | #define Unlock_Task system__soft_links__unlock_task | |
b0df4321 | 672 | extern 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 |
678 | extern struct tm *__gnat_localtime_r PARAMS ((const time_t *, |
679 | struct tm *)); | |
996ae0b0 RK |
680 | |
681 | struct 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 | |
704 | extern struct tm *__gnat_localtime_r PARAMS ((const time_t *, struct tm *)); | |
705 | ||
706 | struct 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 | ||
724 | extern struct tm *__gnat_localtime_r PARAMS ((const time_t *, struct tm *)); | |
725 | ||
726 | struct 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 |