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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [ada/] [sysdep.c] - Blame information for rev 717

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

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

powered by: WebSVN 2.1.0

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