OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [ada/] [sysdep.c] - Blame information for rev 847

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 281 jeremybenn
/****************************************************************************
2
 *                                                                          *
3
 *                         GNAT COMPILER COMPONENTS                         *
4
 *                                                                          *
5
 *                                S Y S D E P                               *
6
 *                                                                          *
7
 *                          C Implementation File                           *
8
 *                                                                          *
9
 *         Copyright (C) 1992-2009, Free Software Foundation, Inc.          *
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 3,  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.                                     *
17
 *                                                                          *
18
 * As a special exception under Section 7 of GPL version 3, you are granted *
19
 * additional permissions described in the GCC Runtime Library Exception,   *
20
 * version 3.1, as published by the Free Software Foundation.               *
21
 *                                                                          *
22
 * You should have received a copy of the GNU General Public License and    *
23
 * a copy of the GCC Runtime Library Exception along with this program;     *
24
 * see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    *
25
 * <http://www.gnu.org/licenses/>.                                          *
26
 *                                                                          *
27
 * GNAT was originally developed  by the GNAT team at  New York University. *
28
 * Extensive contributions were provided by Ada Core Technologies Inc.      *
29
 *                                                                          *
30
 ****************************************************************************/
31
 
32
/* This file contains system dependent symbols that are referenced in the
33
   GNAT Run Time Library */
34
 
35
#ifdef __vxworks
36
#include "ioLib.h"
37
#if ! defined (__VXWORKSMILS__)
38
#include "dosFsLib.h"
39
#endif
40
#if ! defined (__RTP__) && (! defined (VTHREADS) || defined (__VXWORKSMILS__))
41
# include "nfsLib.h"
42
#endif
43
#include "selectLib.h"
44
#include "vxWorks.h"
45
#endif
46
 
47
#ifdef IN_RTS
48
#define POSIX
49
#include "tconfig.h"
50
#include "tsystem.h"
51
#include <fcntl.h>
52
#include <sys/stat.h>
53
#ifdef VMS
54
#include <unixio.h>
55
#endif
56
#else
57
#include "config.h"
58
#include "system.h"
59
#endif
60
 
61
#include <time.h>
62
#include <errno.h>
63
 
64
#if defined (sun) && defined (__SVR4) && !defined (__vxworks)
65
/* The declaration is present in <time.h> but conditionalized
66
   on a couple of macros we don't define.  */
67
extern struct tm *localtime_r(const time_t *, struct tm *);
68
#endif
69
 
70
#include "adaint.h"
71
 
72
/*
73
   mode_read_text
74
   open text file for reading
75
   rt for DOS and Windows NT, r for Unix
76
 
77
   mode_write_text
78
   truncate to zero length or create text file for writing
79
   wt for DOS and Windows NT, w for Unix
80
 
81
   mode_append_text
82
   append; open or create text file for writing at end-of-file
83
   at for DOS and Windows NT, a for Unix
84
 
85
   mode_read_binary
86
   open binary file for reading
87
   rb for DOS and Windows NT, r for Unix
88
 
89
   mode_write_binary
90
   truncate to zero length or create binary file for writing
91
   wb for DOS and Windows NT, w for Unix
92
 
93
   mode_append_binary
94
   append; open or create binary file for writing at end-of-file
95
   ab for DOS and Windows NT, a for Unix
96
 
97
   mode_read_text_plus
98
   open text file for update (reading and writing)
99
   r+t for DOS and Windows NT, r+ for Unix
100
 
101
   mode_write_text_plus
102
   truncate to zero length or create text file for update
103
   w+t for DOS and Windows NT, w+ for Unix
104
 
105
   mode_append_text_plus
106
   append; open or create text file for update, writing at end-of-file
107
   a+t for DOS and Windows NT, a+ for Unix
108
 
109
   mode_read_binary_plus
110
   open binary file for update (reading and writing)
111
   r+b for DOS and Windows NT, r+ for Unix
112
 
113
   mode_write_binary_plus
114
   truncate to zero length or create binary file for update
115
   w+b for DOS and Windows NT, w+ for Unix
116
 
117
   mode_append_binary_plus
118
   append; open or create binary file for update, writing at end-of-file
119
   a+b for DOS and Windows NT, a+ for Unix
120
 
121
   Notes:
122
 
123
   (1) Opening a file with read mode fails if the file does not exist or
124
   cannot be read.
125
 
126
   (2) Opening a file with append mode causes all subsequent writes to the
127
   file to be forced to the then current end-of-file, regardless of
128
   intervening calls to the fseek function.
129
 
130
   (3) When a file is opened with update mode, both input and output may be
131
   performed on the associated stream.  However, output may not be directly
132
   followed by input without an intervening call to the fflush function or
133
   to a file positioning function (fseek, fsetpos, or rewind), and input
134
   may not be directly followed by output without an intervening call to a
135
   file positioning function, unless the input operation encounters
136
   end-of-file.
137
 
138
   The other target dependent declarations here are for the two functions
139
   __gnat_set_binary_mode and __gnat_set_text_mode:
140
 
141
      void __gnat_set_binary_mode (int handle);
142
      void __gnat_set_text_mode   (int handle);
143
 
144
   These functions have no effect in Unix (or similar systems where there is
145
   no distinction between binary and text files), but in DOS (and similar
146
   systems where text mode does CR/LF translation), these functions allow
147
   the mode of the stream with the given handle (fileno can be used to get
148
   the handle of a stream) to be changed dynamically. The returned result
149
   is 0 if no error occurs and -1 if an error occurs.
150
 
151
   Finally there is a boolean (character) variable
152
 
153
      char __gnat_text_translation_required;
154
 
155
   which is zero (false) in Unix mode, and one (true) in DOS mode, with a
156
   true value indicating that text translation is required on text files
157
   and that fopen supports the trailing t and b modifiers.
158
 
159
*/
160
 
161
#if defined(WINNT) || defined (MSDOS) || defined (__EMX__)
162
static const char *mode_read_text = "rt";
163
static const char *mode_write_text = "wt";
164
static const char *mode_append_text = "at";
165
static const char *mode_read_binary = "rb";
166
static const char *mode_write_binary = "wb";
167
static const char *mode_append_binary = "ab";
168
static const char *mode_read_text_plus = "r+t";
169
static const char *mode_write_text_plus = "w+t";
170
static const char *mode_append_text_plus = "a+t";
171
static const char *mode_read_binary_plus = "r+b";
172
static const char *mode_write_binary_plus = "w+b";
173
static const char *mode_append_binary_plus = "a+b";
174
const char __gnat_text_translation_required = 1;
175
 
176
void
177
__gnat_set_binary_mode (int handle)
178
{
179
  _setmode (handle, O_BINARY);
180
}
181
 
182
void
183
__gnat_set_text_mode (int handle)
184
{
185
  _setmode (handle, O_TEXT);
186
}
187
 
188
#ifdef __MINGW32__
189
#include <windows.h>
190
 
191
/* Return the name of the tty.   Under windows there is no name for
192
   the tty, so this function, if connected to a tty, returns the generic name
193
   "console".  */
194
 
195
char *
196
__gnat_ttyname (int filedes)
197
{
198
  if (isatty (filedes))
199
    return "console";
200
  else
201
    return NULL;
202
}
203
 
204
/* This function is needed to fix a bug under Win95/98. Under these platforms
205
   doing :
206
                ch1 = getch();
207
                ch2 = fgetc (stdin);
208
 
209
   will put the same character into ch1 and ch2. It seem that the character
210
   read by getch() is not correctly removed from the buffer. Even a
211
   fflush(stdin) does not fix the bug. This bug does not appear under Window
212
   NT. So we have two version of this routine below one for 95/98 and one for
213
   NT/2000 version of Windows. There is also a special routine (winflushinit)
214
   that will be called only the first time to check which version of Windows
215
   we are running running on to set the right routine to use.
216
 
217
   This problem occurs when using Text_IO.Get_Line after Text_IO.Get_Immediate
218
   for example.
219
 
220
   Calling FlushConsoleInputBuffer just after getch() fix the bug under
221
   95/98. */
222
 
223
#ifdef RTX
224
 
225
static void winflush_nt (void);
226
 
227
/* winflush_function will do nothing since we only have problems with Windows
228
   95/98 which are not supported by RTX. */
229
 
230
static void (*winflush_function) (void) = winflush_nt;
231
 
232
static void
233
winflush_nt (void)
234
{
235
  /* Does nothing as there is no problem under NT.  */
236
}
237
 
238
#else
239
 
240
static void winflush_init (void);
241
 
242
static void winflush_95 (void);
243
 
244
static void winflush_nt (void);
245
 
246
int __gnat_is_windows_xp (void);
247
 
248
/* winflusfunction is set first to the winflushinit function which will check
249
   the OS version 95/98 or NT/2000 */
250
 
251
static void (*winflush_function) (void) = winflush_init;
252
 
253
/* This function does the runtime check of the OS version and then sets
254
   winflush_function to the appropriate function and then call it. */
255
 
256
static void
257
winflush_init (void)
258
{
259
  DWORD dwVersion = GetVersion();
260
 
261
  if (dwVersion < 0x80000000)                /* Windows NT/2000 */
262
    winflush_function = winflush_nt;
263
  else                                       /* Windows 95/98   */
264
    winflush_function = winflush_95;
265
 
266
  (*winflush_function)();      /* Perform the 'flush' */
267
 
268
}
269
 
270
static void
271
winflush_95 (void)
272
{
273
  FlushConsoleInputBuffer (GetStdHandle (STD_INPUT_HANDLE));
274
}
275
 
276
static void
277
winflush_nt (void)
278
{
279
  /* Does nothing as there is no problem under NT.  */
280
}
281
 
282
int
283
__gnat_is_windows_xp (void)
284
{
285
  static int is_win_xp=0, is_win_xp_checked=0;
286
 
287
  if (!is_win_xp_checked)
288
    {
289
      OSVERSIONINFO version;
290
 
291
      is_win_xp_checked = 1;
292
 
293
      memset (&version, 0, sizeof (version));
294
      version.dwOSVersionInfoSize = sizeof (version);
295
 
296
      is_win_xp = GetVersionEx (&version)
297
        && version.dwPlatformId == VER_PLATFORM_WIN32_NT
298
        && (version.dwMajorVersion > 5
299
            || (version.dwMajorVersion == 5 && version.dwMinorVersion >= 1));
300
    }
301
  return is_win_xp;
302
}
303
 
304
#endif
305
 
306
#endif
307
 
308
#else
309
 
310
static const char *mode_read_text = "r";
311
static const char *mode_write_text = "w";
312
static const char *mode_append_text = "a";
313
static const char *mode_read_binary = "r";
314
static const char *mode_write_binary = "w";
315
static const char *mode_append_binary = "a";
316
static const char *mode_read_text_plus = "r+";
317
static const char *mode_write_text_plus = "w+";
318
static const char *mode_append_text_plus = "a+";
319
static const char *mode_read_binary_plus = "r+";
320
static const char *mode_write_binary_plus = "w+";
321
static const char *mode_append_binary_plus = "a+";
322
const char __gnat_text_translation_required = 0;
323
 
324
/* These functions do nothing in non-DOS systems. */
325
 
326
void
327
__gnat_set_binary_mode (int handle ATTRIBUTE_UNUSED)
328
{
329
}
330
 
331
void
332
__gnat_set_text_mode (int handle ATTRIBUTE_UNUSED)
333
{
334
}
335
char *
336
__gnat_ttyname (int filedes)
337
{
338
#if defined (__vxworks) || defined (__nucleus)
339
  return "";
340
#else
341
  extern char *ttyname (int);
342
 
343
  return ttyname (filedes);
344
#endif /* defined (__vxworks) || defined (__nucleus) */
345
}
346
#endif
347
 
348
#if defined (linux) || defined (sun) || defined (sgi) || defined (__EMX__) \
349
  || (defined (__osf__) && ! defined (__alpha_vxworks)) || defined (WINNT) \
350
  || defined (__MACHTEN__) || defined (__hpux__) || defined (_AIX) \
351
  || (defined (__svr4__) && defined (i386)) || defined (__Lynx__) \
352
  || defined (__CYGWIN__) || defined (__FreeBSD__) || defined (__OpenBSD__) \
353
  || defined (__GLIBC__) || defined (__APPLE__)
354
 
355
#ifdef __MINGW32__
356
#if OLD_MINGW
357
#include <termios.h>
358
#else
359
#include <conio.h>  /* for getch(), kbhit() */
360
#endif
361
#else
362
#include <termios.h>
363
#endif
364
 
365
#else
366
#if defined (VMS)
367
extern char *decc$ga_stdscr;
368
static int initted = 0;
369
#endif
370
#endif
371
 
372
/* Implements the common processing for getc_immediate and
373
   getc_immediate_nowait. */
374
 
375
extern void getc_immediate (FILE *, int *, int *);
376
extern void getc_immediate_nowait (FILE *, int *, int *, int *);
377
extern void getc_immediate_common (FILE *, int *, int *, int *, int);
378
 
379
/* Called by Get_Immediate (Foo); */
380
 
381
void
382
getc_immediate (FILE *stream, int *ch, int *end_of_file)
383
{
384
  int avail;
385
 
386
  getc_immediate_common (stream, ch, end_of_file, &avail, 1);
387
}
388
 
389
/* Called by Get_Immediate (Foo, Available); */
390
 
391
void
392
getc_immediate_nowait (FILE *stream, int *ch, int *end_of_file, int *avail)
393
{
394
  getc_immediate_common (stream, ch, end_of_file, avail, 0);
395
}
396
 
397
/* Called by getc_immediate () and getc_immediate_nowait () */
398
 
399
void
400
getc_immediate_common (FILE *stream,
401
                       int *ch,
402
                       int *end_of_file,
403
                       int *avail,
404
                       int waiting)
405
{
406
#if defined (linux) || defined (sun) || defined (sgi) || defined (__EMX__) \
407
    || (defined (__osf__) && ! defined (__alpha_vxworks)) \
408
    || defined (__CYGWIN32__) || defined (__MACHTEN__) || defined (__hpux__) \
409
    || defined (_AIX) || (defined (__svr4__) && defined (i386)) \
410
    || defined (__Lynx__) || defined (__FreeBSD__) || defined (__OpenBSD__) \
411
    || defined (__GLIBC__) || defined (__APPLE__)
412
  char c;
413
  int nread;
414
  int good_one = 0;
415
  int eof_ch = 4; /* Ctrl-D */
416
  int fd = fileno (stream);
417
  struct termios otermios_rec, termios_rec;
418
 
419
  if (isatty (fd))
420
    {
421
      tcgetattr (fd, &termios_rec);
422
      memcpy (&otermios_rec, &termios_rec, sizeof (struct termios));
423
 
424
      /* Set RAW mode, with no echo */
425
      termios_rec.c_lflag = termios_rec.c_lflag & ~ICANON & ~ECHO;
426
 
427
#if defined(linux) || defined (sun) || defined (sgi) || defined (__EMX__) \
428
    || defined (__osf__) || defined (__MACHTEN__) || defined (__hpux__) \
429
    || defined (_AIX) || (defined (__svr4__) && defined (i386)) \
430
    || defined (__Lynx__) || defined (__FreeBSD__) || defined (__OpenBSD__) \
431
    || defined (__GLIBC__) || defined (__APPLE__)
432
      eof_ch = termios_rec.c_cc[VEOF];
433
 
434
      /* If waiting (i.e. Get_Immediate (Char)), set MIN = 1 and wait for
435
         a character forever. This doesn't seem to effect Ctrl-Z or
436
         Ctrl-C processing except on OS/2 where Ctrl-C won't work right
437
         unless we do a read loop. Luckily we can delay a bit between
438
         iterations. If not waiting (i.e. Get_Immediate (Char, Available)),
439
         don't wait for anything but timeout immediately. */
440
#ifdef __EMX__
441
      termios_rec.c_cc[VMIN] = 0;
442
      termios_rec.c_cc[VTIME] = waiting;
443
#else
444
      termios_rec.c_cc[VMIN] = waiting;
445
      termios_rec.c_cc[VTIME] = 0;
446
#endif
447
#endif
448
      tcsetattr (fd, TCSANOW, &termios_rec);
449
 
450
      while (! good_one)
451
        {
452
          /* Read is used here instead of fread, because fread doesn't
453
             work on Solaris5 and Sunos4 in this situation.  Maybe because we
454
             are mixing calls that use file descriptors and streams. */
455
          nread = read (fd, &c, 1);
456
          if (nread > 0)
457
            {
458
              /* On Unix terminals, Ctrl-D (EOT) is an End of File. */
459
              if (c == eof_ch)
460
                {
461
                  *avail = 0;
462
                  *end_of_file = 1;
463
                  good_one = 1;
464
                }
465
 
466
              /* Everything else is ok */
467
              else if (c != eof_ch)
468
                {
469
                  *avail = 1;
470
                  *end_of_file = 0;
471
                  good_one = 1;
472
                }
473
            }
474
 
475
          else if (! waiting)
476
            {
477
              *avail = 0;
478
              *end_of_file = 0;
479
              good_one = 1;
480
            }
481
          else
482
            good_one = 0;
483
        }
484
 
485
      tcsetattr (fd, TCSANOW, &otermios_rec);
486
      *ch = c;
487
    }
488
 
489
  else
490
#elif defined (VMS)
491
  int fd = fileno (stream);
492
 
493
  if (isatty (fd))
494
    {
495
      if (initted == 0)
496
        {
497
          decc$bsd_initscr ();
498
          initted = 1;
499
        }
500
 
501
      decc$bsd_cbreak ();
502
      *ch = decc$bsd_wgetch (decc$ga_stdscr);
503
 
504
      if (*ch == 4)
505
        *end_of_file = 1;
506
      else
507
        *end_of_file = 0;
508
 
509
      *avail = 1;
510
      decc$bsd_nocbreak ();
511
    }
512
  else
513
#elif defined (__MINGW32__)
514
  int fd = fileno (stream);
515
  int char_waiting;
516
  int eot_ch = 4; /* Ctrl-D */
517
 
518
  if (isatty (fd))
519
    {
520
      if (waiting)
521
        {
522
          *ch = getch ();
523
          (*winflush_function) ();
524
 
525
          if (*ch == eot_ch)
526
            *end_of_file = 1;
527
          else
528
            *end_of_file = 0;
529
 
530
          *avail = 1;
531
        }
532
      else /* ! waiting */
533
        {
534
          char_waiting = kbhit();
535
 
536
          if (char_waiting == 1)
537
            {
538
              *avail = 1;
539
              *ch = getch ();
540
              (*winflush_function) ();
541
 
542
              if (*ch == eot_ch)
543
                *end_of_file = 1;
544
              else
545
                *end_of_file = 0;
546
            }
547
          else
548
            {
549
              *avail = 0;
550
              *end_of_file = 0;
551
            }
552
        }
553
    }
554
  else
555
#elif defined (__vxworks)
556
  /* Bit masks of file descriptors to read from.  */
557
  struct fd_set readFds;
558
  /* Timeout before select returns if nothing can be read.  */
559
  struct timeval timeOut;
560
  char c;
561
  int fd = fileno (stream);
562
  int nread;
563
  int option;
564
  int readable;
565
  int status;
566
  int width;
567
 
568
  if (isatty (fd))
569
    {
570
      /* If we do not want to wait, we have to set up fd in RAW mode. This
571
         should be done outside this function as setting fd in RAW mode under
572
         vxWorks flushes the buffer of fd. If the RAW mode was set here, the
573
         buffer would be empty and we would always return that no character
574
         is available */
575
      if (! waiting)
576
        {
577
          /* Initialization of timeOut for its use with select.  */
578
          timeOut.tv_sec  = 0;
579
          timeOut.tv_usec = 0;
580
 
581
          /* Initialization of readFds for its use with select;
582
             FD is the only file descriptor to be monitored */
583
          FD_ZERO (&readFds);
584
          FD_SET (fd, &readFds);
585
          width = 2;
586
 
587
          /* We do all this processing to emulate a non blocking read.  */
588
          readable = select (width, &readFds, NULL, NULL, &timeOut);
589
          if (readable == ERROR)
590
            *avail = -1, *end_of_file = -1;
591
          /* No character available in input.  */
592
          else if (readable == 0)
593
            *avail = 0, *end_of_file = 0;
594
          else
595
            {
596
              nread = read (fd, &c, 1);
597
              if (nread > 0)
598
                *avail = 1, *end_of_file = 0;
599
              /* End Of File. */
600
              else if (nread == 0)
601
                *avail = 0, *end_of_file = 1;
602
              /* Error.  */
603
              else
604
                *avail = -1, *end_of_file = -1;
605
            }
606
        }
607
 
608
      /* We have to wait until we get a character */
609
      else
610
        {
611
          *avail = -1;
612
          *end_of_file = -1;
613
 
614
          /* Save the current mode of FD.  */
615
          option = ioctl (fd, FIOGETOPTIONS, 0);
616
 
617
          /* Set FD in RAW mode.  */
618
          status = ioctl (fd, FIOSETOPTIONS, OPT_RAW);
619
          if (status != -1)
620
            {
621
              nread = read (fd, &c, 1);
622
              if (nread > 0)
623
                *avail = 1, *end_of_file = 0;
624
              /* End of file.  */
625
              else if (nread == 0)
626
                *avail = 0, *end_of_file = 1;
627
              /* Else there is an ERROR.  */
628
            }
629
 
630
          /* Revert FD to its previous mode. */
631
          status = ioctl (fd, FIOSETOPTIONS, option);
632
        }
633
 
634
      *ch = c;
635
    }
636
  else
637
#endif
638
    {
639
      /* If we're not on a terminal, then we don't need any fancy processing.
640
         Also this is the only thing that's left if we're not on one of the
641
         supported systems; which means that for non supported systems,
642
         get_immediate may wait for a carriage return on terminals. */
643
      *ch = fgetc (stream);
644
      if (feof (stream))
645
        {
646
          *end_of_file = 1;
647
          *avail = 0;
648
        }
649
      else
650
        {
651
          *end_of_file = 0;
652
          *avail = 1;
653
        }
654
    }
655
}
656
 
657
/* The following definitions are provided in NT to support Windows based
658
   Ada programs.  */
659
 
660
#ifdef WINNT
661
#include <windows.h>
662
 
663
/* Provide functions to echo the values passed to WinMain (windows bindings
664
   will want to import these).  We use the same names as the routines used
665
   by AdaMagic for compatibility.  */
666
 
667
char *rts_get_hInstance (void);
668
char *rts_get_hPrevInstance (void);
669
char *rts_get_lpCommandLine (void);
670
int   rts_get_nShowCmd (void);
671
 
672
char *
673
rts_get_hInstance (void)
674
{
675
  return (char *)GetModuleHandleA (0);
676
}
677
 
678
char *
679
rts_get_hPrevInstance (void)
680
{
681
  return 0;
682
}
683
 
684
char *
685
rts_get_lpCommandLine (void)
686
{
687
  return GetCommandLineA ();
688
}
689
 
690
int
691
rts_get_nShowCmd (void)
692
{
693
  return 1;
694
}
695
 
696
#endif /* WINNT */
697
#ifdef VMS
698
 
699
/* This gets around a problem with using the old threads library on VMS 7.0. */
700
 
701
extern long get_gmtoff (void);
702
 
703
long
704
get_gmtoff (void)
705
{
706
  time_t t;
707
  struct tm *ts;
708
 
709
  t = time ((time_t) 0);
710
  ts = localtime (&t);
711
  return ts->tm_gmtoff;
712
}
713
#endif
714
 
715
/* This value is returned as the time zone offset when a valid value
716
   cannot be determined. It is simply a bizarre value that will never
717
   occur. It is 3 days plus 73 seconds (offset is in seconds). */
718
 
719
long __gnat_invalid_tzoff = 259273;
720
 
721
/* Definition of __gnat_localtime_r used by a-calend.adb */
722
 
723
#if defined (__EMX__) || defined (__MINGW32__)
724
 
725
#ifdef CERT
726
 
727
/* For the Cert run times on native Windows we use dummy functions
728
   for locking and unlocking tasks since we do not support multiple
729
   threads on this configuration (Cert run time on native Windows). */
730
 
731
void dummy (void) {}
732
 
733
void (*Lock_Task) ()   = &dummy;
734
void (*Unlock_Task) () = &dummy;
735
 
736
#else
737
 
738
#define Lock_Task system__soft_links__lock_task
739
extern void (*Lock_Task) (void);
740
 
741
#define Unlock_Task system__soft_links__unlock_task
742
extern void (*Unlock_Task) (void);
743
 
744
#endif
745
 
746
/* Reentrant localtime for Windows and OS/2. */
747
 
748
extern void
749
__gnat_localtime_tzoff (const time_t *, long *);
750
 
751
static const unsigned long long w32_epoch_offset = 11644473600ULL;
752
void
753
__gnat_localtime_tzoff (const time_t *timer, long *off)
754
{
755
  union
756
  {
757
    FILETIME ft_time;
758
    unsigned long long ull_time;
759
  } utc_time, local_time;
760
 
761
  SYSTEMTIME utc_sys_time, local_sys_time;
762
  TIME_ZONE_INFORMATION tzi;
763
 
764
  BOOL  status = 1;
765
  DWORD tzi_status;
766
 
767
  (*Lock_Task) ();
768
 
769
#ifdef RTX
770
 
771
  tzi_status = GetTimeZoneInformation (&tzi);
772
  *off = tzi.Bias;
773
  if (tzi_status == TIME_ZONE_ID_STANDARD)
774
     /* The system is operating in the range covered by the StandardDate
775
        member. */
776
     *off = *off + tzi.StandardBias;
777
  else if (tzi_status == TIME_ZONE_ID_DAYLIGHT)
778
     /* The system is operating in the range covered by the DaylightDate
779
        member. */
780
     *off = *off + tzi.DaylightBias;
781
  *off = *off * -60;
782
 
783
#else
784
 
785
  /* First convert unix time_t structure to windows FILETIME format.  */
786
  utc_time.ull_time = ((unsigned long long) *timer + w32_epoch_offset)
787
                      * 10000000ULL;
788
 
789
  tzi_status = GetTimeZoneInformation (&tzi);
790
 
791
  /* If GetTimeZoneInformation does not return a value between 0 and 2 then
792
     it means that we were not able to retrieve timezone informations.
793
     Note that we cannot use here FileTimeToLocalFileTime as Windows will use
794
     in always in this case the current timezone setting. As suggested on
795
     MSDN we use the following three system calls to get the right information.
796
     Note also that starting with Windows Vista new functions are provided to
797
     get timezone settings that depend on the year. We cannot use them as we
798
     still support Windows XP and Windows 2003.  */
799
  status = (tzi_status >= 0 && tzi_status <= 2)
800
     && FileTimeToSystemTime (&utc_time.ft_time, &utc_sys_time)
801
     && SystemTimeToTzSpecificLocalTime (&tzi, &utc_sys_time, &local_sys_time)
802
     && SystemTimeToFileTime (&local_sys_time, &local_time.ft_time);
803
 
804
  if (!status)
805
     /* An error occurs so return invalid_tzoff.  */
806
     *off = __gnat_invalid_tzoff;
807
  else
808
     if (local_time.ull_time > utc_time.ull_time)
809
        *off = (long) ((local_time.ull_time - utc_time.ull_time) / 10000000ULL);
810
     else
811
        *off = - (long) ((utc_time.ull_time - local_time.ull_time) / 10000000ULL);
812
 
813
#endif
814
 
815
  (*Unlock_Task) ();
816
}
817
 
818
#else
819
 
820
/* On Lynx, all time values are treated in GMT */
821
 
822
#if defined (__Lynx__)
823
 
824
/* As of LynxOS 3.1.0a patch level 040, LynuxWorks changes the
825
   prototype to the C library function localtime_r from the POSIX.4
826
   Draft 9 to the POSIX 1.c version. Before this change the following
827
   spec is required. Only use when ___THREADS_POSIX4ad4__ is defined,
828
   the Lynx convention when building against the legacy API. */
829
 
830
extern void
831
__gnat_localtime_tzoff (const time_t *, long *);
832
 
833
void
834
__gnat_localtime_tzoff (const time_t *timer, long *off)
835
{
836
  *off = 0;
837
}
838
 
839
#else
840
 
841
/* VMS does not need __gnat_locatime_tzoff */
842
 
843
#if defined (VMS)
844
 
845
/* Other targets except Lynx, VMS and Windows provide a standard locatime_r */
846
 
847
#else
848
 
849
#define Lock_Task system__soft_links__lock_task
850
extern void (*Lock_Task) (void);
851
 
852
#define Unlock_Task system__soft_links__unlock_task
853
extern void (*Unlock_Task) (void);
854
 
855
extern void
856
__gnat_localtime_tzoff (const time_t *, long *);
857
 
858
void
859
__gnat_localtime_tzoff (const time_t *timer, long *off)
860
{
861
  struct tm tp;
862
 
863
/* AIX, HPUX, SGI Irix, Sun Solaris */
864
#if defined (_AIX) || defined (__hpux__) || defined (sgi) || defined (sun)
865
{
866
  (*Lock_Task) ();
867
 
868
  localtime_r (timer, &tp);
869
  *off = (long) -timezone;
870
 
871
  (*Unlock_Task) ();
872
 
873
  /* Correct the offset if Daylight Saving Time is in effect */
874
 
875
  if (tp.tm_isdst > 0)
876
    *off = *off + 3600;
877
}
878
 
879
/* VxWorks */
880
#elif defined (__vxworks)
881
#include <stdlib.h>
882
{
883
  (*Lock_Task) ();
884
 
885
  localtime_r (timer, &tp);
886
 
887
  /* Try to read the environment variable TIMEZONE. The variable may not have
888
     been initialize, in that case return an offset of zero (0) for UTC. */
889
 
890
  char *tz_str = getenv ("TIMEZONE");
891
 
892
  if ((tz_str == NULL) || (*tz_str == '\0'))
893
    *off = 0;
894
  else
895
  {
896
    char *tz_start, *tz_end;
897
 
898
    /* The format of the data contained in TIMEZONE is N::U:S:E where N is the
899
       name of the time zone, U are the minutes difference from UTC, S is the
900
       start of DST in mmddhh and E is the end of DST in mmddhh. Extracting
901
       the value of U involves setting two pointers, one at the beginning and
902
       one at the end of the value. The end pointer is then set to null in
903
       order to delimit a string slice for atol to process. */
904
 
905
    tz_start = index (tz_str, ':') + 2;
906
    tz_end = index (tz_start, ':');
907
    tz_end = '\0';
908
 
909
    /* The Ada layer expects an offset in seconds. Note that we must reverse
910
       the sign of the result since west is positive and east is negative on
911
       VxWorks targets. */
912
 
913
    *off = -atol (tz_start) * 60;
914
 
915
    /* Correct the offset if Daylight Saving Time is in effect */
916
 
917
    if (tp.tm_isdst > 0)
918
      *off = *off + 3600;
919
  }
920
 
921
  (*Unlock_Task) ();
922
}
923
 
924
/* Darwin, Free BSD, Linux, Tru64, where component tm_gmtoff is present in
925
   struct tm */
926
 
927
#elif defined (__APPLE__) || defined (__FreeBSD__) || defined (linux) ||\
928
     (defined (__alpha__) && defined (__osf__)) || defined (__GLIBC__)
929
{
930
  localtime_r (timer, &tp);
931
  *off = tp.tm_gmtoff;
932
}
933
 
934
/* Default: treat all time values in GMT */
935
 
936
#else
937
  *off = 0;
938
 
939
#endif
940
}
941
 
942
#endif
943
#endif
944
#endif
945
 
946
#ifdef __vxworks
947
 
948
#include <taskLib.h>
949
 
950
/* __gnat_get_task_options is used by s-taprop.adb only for VxWorks. This
951
   function returns the options to be set when creating a new task. It fetches
952
   the options assigned to the current task (parent), so offering some user
953
   level control over the options for a task hierarchy. It forces VX_FP_TASK
954
   because it is almost always required. On processors with the SPE
955
   category, VX_SPE_TASK is needed to enable the SPE. */
956
extern int __gnat_get_task_options (void);
957
 
958
int
959
__gnat_get_task_options (void)
960
{
961
  int options;
962
 
963
  /* Get the options for the task creator */
964
  taskOptionsGet (taskIdSelf (), &options);
965
 
966
  /* Force VX_FP_TASK because it is almost always required */
967
  options |= VX_FP_TASK;
968
#if defined (__SPE__)
969
  options |= VX_SPE_TASK;
970
#endif
971
 
972
  /* Mask those bits that are not under user control */
973
#ifdef VX_USR_TASK_OPTIONS
974
  return options & VX_USR_TASK_OPTIONS;
975
#else
976
  return options;
977
#endif
978
}
979
 
980
#endif
981
 
982
int
983
__gnat_is_file_not_found_error (int errno_val) {
984
   switch (errno_val) {
985
      case ENOENT:
986
#ifdef __vxworks
987
      /* In the case of VxWorks, we also have to take into account various
988
       * filesystem-specific variants of this error.
989
       */
990
#if ! defined (__VXWORKSMILS__)
991
      case S_dosFsLib_FILE_NOT_FOUND:
992
#endif
993
#if ! defined (__RTP__) && (! defined (VTHREADS) || defined (__VXWORKSMILS__))
994
      case S_nfsLib_NFSERR_NOENT:
995
#endif
996
#endif
997
         return 1;
998
 
999
      default:
1000
         return 0;
1001
   }
1002
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.