aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.8.3/gcc/ada/sysdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.8.3/gcc/ada/sysdep.c')
-rw-r--r--gcc-4.8.3/gcc/ada/sysdep.c974
1 files changed, 974 insertions, 0 deletions
diff --git a/gcc-4.8.3/gcc/ada/sysdep.c b/gcc-4.8.3/gcc/ada/sysdep.c
new file mode 100644
index 000000000..1eec8b96f
--- /dev/null
+++ b/gcc-4.8.3/gcc/ada/sysdep.c
@@ -0,0 +1,974 @@
+/****************************************************************************
+ * *
+ * GNAT COMPILER COMPONENTS *
+ * *
+ * S Y S D E P *
+ * *
+ * C Implementation File *
+ * *
+ * Copyright (C) 1992-2012, Free Software Foundation, Inc. *
+ * *
+ * GNAT is free software; you can redistribute it and/or modify it under *
+ * terms of the GNU General Public License as published by the Free Soft- *
+ * ware Foundation; either version 3, or (at your option) any later ver- *
+ * sion. GNAT is distributed in the hope that it will be useful, but WITH- *
+ * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
+ * or FITNESS FOR A PARTICULAR PURPOSE. *
+ * *
+ * As a special exception under Section 7 of GPL version 3, you are granted *
+ * additional permissions described in the GCC Runtime Library Exception, *
+ * version 3.1, as published by the Free Software Foundation. *
+ * *
+ * You should have received a copy of the GNU General Public License and *
+ * a copy of the GCC Runtime Library Exception along with this program; *
+ * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ * *
+ * GNAT was originally developed by the GNAT team at New York University. *
+ * Extensive contributions were provided by Ada Core Technologies Inc. *
+ * *
+ ****************************************************************************/
+
+/* This file contains system dependent symbols that are referenced in the
+ GNAT Run Time Library */
+
+#ifdef __vxworks
+#include "ioLib.h"
+#if ! defined (VTHREADS)
+#include "dosFsLib.h"
+#endif
+#if ! defined (__RTP__) && (! defined (VTHREADS) || defined (__VXWORKSMILS__))
+# include "nfsLib.h"
+#endif
+#include "selectLib.h"
+#include "vxWorks.h"
+#endif
+
+#ifdef __ANDROID__
+#undef linux
+#endif
+
+#ifdef IN_RTS
+#define POSIX
+#include "tconfig.h"
+#include "tsystem.h"
+#include <fcntl.h>
+#include <sys/stat.h>
+#ifdef VMS
+#include <unixio.h>
+#endif
+#else
+#include "config.h"
+#include "system.h"
+#endif
+
+#include <time.h>
+#include <errno.h>
+
+#if defined (sun) && defined (__SVR4) && !defined (__vxworks)
+/* The declaration is present in <time.h> but conditionalized
+ on a couple of macros we don't define. */
+extern struct tm *localtime_r(const time_t *, struct tm *);
+#endif
+
+#include "adaint.h"
+
+/* Don't use macros versions of this functions on VxWorks since they cause
+ imcompatible changes in some VxWorks versions */
+#ifdef __vxworks
+#undef getchar
+#undef putchar
+#undef feof
+#undef ferror
+#undef fileno
+#endif
+
+/*
+ Notes:
+
+ (1) Opening a file with read mode fails if the file does not exist or
+ cannot be read.
+
+ (2) Opening a file with append mode causes all subsequent writes to the
+ file to be forced to the then current end-of-file, regardless of
+ intervening calls to the fseek function.
+
+ (3) When a file is opened with update mode, both input and output may be
+ performed on the associated stream. However, output may not be directly
+ followed by input without an intervening call to the fflush function or
+ to a file positioning function (fseek, fsetpos, or rewind), and input
+ may not be directly followed by output without an intervening call to a
+ file positioning function, unless the input operation encounters
+ end-of-file.
+
+ The other target dependent declarations here are for the two functions
+ __gnat_set_binary_mode and __gnat_set_text_mode:
+
+ void __gnat_set_binary_mode (int handle);
+ void __gnat_set_text_mode (int handle);
+
+ These functions have no effect in Unix (or similar systems where there is
+ no distinction between binary and text files), but in DOS (and similar
+ systems where text mode does CR/LF translation), these functions allow
+ the mode of the stream with the given handle (fileno can be used to get
+ the handle of a stream) to be changed dynamically. The returned result
+ is 0 if no error occurs and -1 if an error occurs.
+
+ Finally there is a boolean (character) variable
+
+ char __gnat_text_translation_required;
+
+ which is zero (false) in Unix mode, and one (true) in DOS mode, with a
+ true value indicating that text translation is required on text files
+ and that fopen supports the trailing t and b modifiers.
+
+*/
+
+#if defined (WINNT) || defined (__CYGWIN__)
+
+const char __gnat_text_translation_required = 1;
+
+#ifdef __CYGWIN__
+#define WIN_SETMODE setmode
+#include <io.h>
+#else
+#define WIN_SETMODE _setmode
+#endif
+
+void
+__gnat_set_binary_mode (int handle)
+{
+ WIN_SETMODE (handle, O_BINARY);
+}
+
+void
+__gnat_set_text_mode (int handle)
+{
+ WIN_SETMODE (handle, O_TEXT);
+}
+
+#ifdef __CYGWIN__
+
+char *
+__gnat_ttyname (int filedes)
+{
+ extern char *ttyname (int);
+
+ return ttyname (filedes);
+}
+
+#endif /* __CYGWIN__ */
+
+#if defined (__CYGWIN__) || defined (__MINGW32__)
+#include <windows.h>
+
+#ifndef RTX
+
+int __gnat_is_windows_xp (void);
+
+int
+__gnat_is_windows_xp (void)
+{
+ static int is_win_xp=0, is_win_xp_checked=0;
+
+ if (!is_win_xp_checked)
+ {
+ OSVERSIONINFO version;
+
+ is_win_xp_checked = 1;
+
+ memset (&version, 0, sizeof (version));
+ version.dwOSVersionInfoSize = sizeof (version);
+
+ is_win_xp = GetVersionEx (&version)
+ && version.dwPlatformId == VER_PLATFORM_WIN32_NT
+ && (version.dwMajorVersion > 5
+ || (version.dwMajorVersion == 5 && version.dwMinorVersion >= 1));
+ }
+ return is_win_xp;
+}
+
+#endif /* !RTX */
+
+/* Get the bounds of the stack. The stack pointer is supposed to be
+ initialized to BASE when a thread is created and the stack can be extended
+ to LIMIT before reaching a guard page.
+ Note: for the main thread, the system automatically extend the stack, so
+ LIMIT is only the current limit. */
+
+void
+__gnat_get_stack_bounds (void **base, void **limit)
+{
+ NT_TIB *tib;
+
+ /* We know that the first field of the TEB is the TIB. */
+ tib = (NT_TIB *)NtCurrentTeb ();
+
+ *base = tib->StackBase;
+ *limit = tib->StackLimit;
+}
+
+#endif /* __CYGWIN__ || __MINGW32__ */
+
+#ifdef __MINGW32__
+
+/* Return the name of the tty. Under windows there is no name for
+ the tty, so this function, if connected to a tty, returns the generic name
+ "console". */
+
+char *
+__gnat_ttyname (int filedes)
+{
+ if (isatty (filedes))
+ return "console";
+ else
+ return NULL;
+}
+
+#endif /* __MINGW32__ */
+
+#else
+
+const char __gnat_text_translation_required = 0;
+
+/* These functions do nothing in non-DOS systems. */
+
+void
+__gnat_set_binary_mode (int handle ATTRIBUTE_UNUSED)
+{
+}
+
+void
+__gnat_set_text_mode (int handle ATTRIBUTE_UNUSED)
+{
+}
+char *
+__gnat_ttyname (int filedes)
+{
+#if defined (__vxworks) || defined (__nucleus)
+ return "";
+#else
+ extern char *ttyname (int);
+
+ return ttyname (filedes);
+#endif /* defined (__vxworks) || defined (__nucleus) */
+}
+#endif
+
+#if defined (linux) || defined (sun) \
+ || defined (WINNT) \
+ || defined (__MACHTEN__) || defined (__hpux__) || defined (_AIX) \
+ || (defined (__svr4__) && defined (i386)) || defined (__Lynx__) \
+ || defined (__CYGWIN__) || defined (__FreeBSD__) || defined (__OpenBSD__) \
+ || defined (__GLIBC__) || defined (__APPLE__)
+
+# ifdef __MINGW32__
+# if OLD_MINGW
+# include <termios.h>
+# else
+# include <conio.h> /* for getch(), kbhit() */
+# endif
+# else
+# include <termios.h>
+# endif
+
+#else
+# if defined (VMS)
+extern char *decc$ga_stdscr;
+static int initted = 0;
+# endif
+#endif
+
+/* Implements the common processing for getc_immediate and
+ getc_immediate_nowait. */
+
+extern void getc_immediate (FILE *, int *, int *);
+extern void getc_immediate_nowait (FILE *, int *, int *, int *);
+extern void getc_immediate_common (FILE *, int *, int *, int *, int);
+
+/* Called by Get_Immediate (Foo); */
+
+void
+getc_immediate (FILE *stream, int *ch, int *end_of_file)
+{
+ int avail;
+
+ getc_immediate_common (stream, ch, end_of_file, &avail, 1);
+}
+
+/* Called by Get_Immediate (Foo, Available); */
+
+void
+getc_immediate_nowait (FILE *stream, int *ch, int *end_of_file, int *avail)
+{
+ getc_immediate_common (stream, ch, end_of_file, avail, 0);
+}
+
+/* Called by getc_immediate () and getc_immediate_nowait () */
+
+void
+getc_immediate_common (FILE *stream,
+ int *ch,
+ int *end_of_file,
+ int *avail,
+ int waiting)
+{
+#if defined (linux) || defined (sun) \
+ || defined (__CYGWIN32__) || defined (__MACHTEN__) || defined (__hpux__) \
+ || defined (_AIX) || (defined (__svr4__) && defined (i386)) \
+ || defined (__Lynx__) || defined (__FreeBSD__) || defined (__OpenBSD__) \
+ || defined (__GLIBC__) || defined (__APPLE__)
+ char c;
+ int nread;
+ int good_one = 0;
+ int eof_ch = 4; /* Ctrl-D */
+ int fd = fileno (stream);
+ struct termios otermios_rec, termios_rec;
+
+ if (isatty (fd))
+ {
+ tcgetattr (fd, &termios_rec);
+ memcpy (&otermios_rec, &termios_rec, sizeof (struct termios));
+
+ /* Set RAW mode, with no echo */
+ termios_rec.c_lflag = termios_rec.c_lflag & ~ICANON & ~ECHO;
+
+#if defined(linux) || defined (sun) \
+ || defined (__MACHTEN__) || defined (__hpux__) \
+ || defined (_AIX) || (defined (__svr4__) && defined (i386)) \
+ || defined (__Lynx__) || defined (__FreeBSD__) || defined (__OpenBSD__) \
+ || defined (__GLIBC__) || defined (__APPLE__)
+ eof_ch = termios_rec.c_cc[VEOF];
+
+ /* If waiting (i.e. Get_Immediate (Char)), set MIN = 1 and wait for
+ a character forever. This doesn't seem to effect Ctrl-Z or
+ Ctrl-C processing.
+ If not waiting (i.e. Get_Immediate (Char, Available)),
+ don't wait for anything but timeout immediately. */
+ termios_rec.c_cc[VMIN] = waiting;
+ termios_rec.c_cc[VTIME] = 0;
+#endif
+ tcsetattr (fd, TCSANOW, &termios_rec);
+
+ while (! good_one)
+ {
+ /* Read is used here instead of fread, because fread doesn't
+ work on Solaris5 and Sunos4 in this situation. Maybe because we
+ are mixing calls that use file descriptors and streams. */
+ nread = read (fd, &c, 1);
+ if (nread > 0)
+ {
+ /* On Unix terminals, Ctrl-D (EOT) is an End of File. */
+ if (c == eof_ch)
+ {
+ *avail = 0;
+ *end_of_file = 1;
+ good_one = 1;
+ }
+
+ /* Everything else is ok */
+ else if (c != eof_ch)
+ {
+ *avail = 1;
+ *end_of_file = 0;
+ good_one = 1;
+ }
+ }
+
+ else if (! waiting)
+ {
+ *avail = 0;
+ *end_of_file = 0;
+ good_one = 1;
+ }
+ else
+ good_one = 0;
+ }
+
+ tcsetattr (fd, TCSANOW, &otermios_rec);
+ *ch = c;
+ }
+
+ else
+#elif defined (VMS)
+ int fd = fileno (stream);
+
+ if (isatty (fd))
+ {
+ if (initted == 0)
+ {
+ decc$bsd_initscr ();
+ initted = 1;
+ }
+
+ decc$bsd_cbreak ();
+ *ch = decc$bsd_wgetch (decc$ga_stdscr);
+
+ if (*ch == 4)
+ *end_of_file = 1;
+ else
+ *end_of_file = 0;
+
+ *avail = 1;
+ decc$bsd_nocbreak ();
+ }
+ else
+#elif defined (__MINGW32__)
+ int fd = fileno (stream);
+ int char_waiting;
+ int eot_ch = 4; /* Ctrl-D */
+
+ if (isatty (fd))
+ {
+ if (waiting)
+ {
+ *ch = getch ();
+
+ if (*ch == eot_ch)
+ *end_of_file = 1;
+ else
+ *end_of_file = 0;
+
+ *avail = 1;
+ }
+ else /* ! waiting */
+ {
+ char_waiting = kbhit();
+
+ if (char_waiting == 1)
+ {
+ *avail = 1;
+ *ch = getch ();
+
+ if (*ch == eot_ch)
+ *end_of_file = 1;
+ else
+ *end_of_file = 0;
+ }
+ else
+ {
+ *avail = 0;
+ *end_of_file = 0;
+ }
+ }
+ }
+ else
+#elif defined (__vxworks)
+ /* Bit masks of file descriptors to read from. */
+ struct fd_set readFds;
+ /* Timeout before select returns if nothing can be read. */
+ struct timeval timeOut;
+ char c;
+ int fd = fileno (stream);
+ int nread;
+ int option;
+ int readable;
+ int status;
+ int width;
+
+ if (isatty (fd))
+ {
+ /* If we do not want to wait, we have to set up fd in RAW mode. This
+ should be done outside this function as setting fd in RAW mode under
+ vxWorks flushes the buffer of fd. If the RAW mode was set here, the
+ buffer would be empty and we would always return that no character
+ is available */
+ if (! waiting)
+ {
+ /* Initialization of timeOut for its use with select. */
+ timeOut.tv_sec = 0;
+ timeOut.tv_usec = 0;
+
+ /* Initialization of readFds for its use with select;
+ FD is the only file descriptor to be monitored */
+ FD_ZERO (&readFds);
+ FD_SET (fd, &readFds);
+ width = 2;
+
+ /* We do all this processing to emulate a non blocking read. */
+ readable = select (width, &readFds, NULL, NULL, &timeOut);
+ if (readable == ERROR)
+ *avail = -1, *end_of_file = -1;
+ /* No character available in input. */
+ else if (readable == 0)
+ *avail = 0, *end_of_file = 0;
+ else
+ {
+ nread = read (fd, &c, 1);
+ if (nread > 0)
+ *avail = 1, *end_of_file = 0;
+ /* End Of File. */
+ else if (nread == 0)
+ *avail = 0, *end_of_file = 1;
+ /* Error. */
+ else
+ *avail = -1, *end_of_file = -1;
+ }
+ }
+
+ /* We have to wait until we get a character */
+ else
+ {
+ *avail = -1;
+ *end_of_file = -1;
+
+ /* Save the current mode of FD. */
+ option = ioctl (fd, FIOGETOPTIONS, 0);
+
+ /* Set FD in RAW mode. */
+ status = ioctl (fd, FIOSETOPTIONS, OPT_RAW);
+ if (status != -1)
+ {
+ nread = read (fd, &c, 1);
+ if (nread > 0)
+ *avail = 1, *end_of_file = 0;
+ /* End of file. */
+ else if (nread == 0)
+ *avail = 0, *end_of_file = 1;
+ /* Else there is an ERROR. */
+ }
+
+ /* Revert FD to its previous mode. */
+ status = ioctl (fd, FIOSETOPTIONS, option);
+ }
+
+ *ch = c;
+ }
+ else
+#endif
+ {
+ /* If we're not on a terminal, then we don't need any fancy processing.
+ Also this is the only thing that's left if we're not on one of the
+ supported systems; which means that for non supported systems,
+ get_immediate may wait for a carriage return on terminals. */
+ *ch = fgetc (stream);
+ if (feof (stream))
+ {
+ *end_of_file = 1;
+ *avail = 0;
+ }
+ else
+ {
+ *end_of_file = 0;
+ *avail = 1;
+ }
+ }
+}
+
+/* The following definitions are provided in NT to support Windows based
+ Ada programs. */
+
+#ifdef WINNT
+#include <windows.h>
+
+/* Provide functions to echo the values passed to WinMain (windows bindings
+ will want to import these). We use the same names as the routines used
+ by AdaMagic for compatibility. */
+
+char *rts_get_hInstance (void);
+char *rts_get_hPrevInstance (void);
+char *rts_get_lpCommandLine (void);
+int rts_get_nShowCmd (void);
+
+char *
+rts_get_hInstance (void)
+{
+ return (char *)GetModuleHandleA (0);
+}
+
+char *
+rts_get_hPrevInstance (void)
+{
+ return 0;
+}
+
+char *
+rts_get_lpCommandLine (void)
+{
+ return GetCommandLineA ();
+}
+
+int
+rts_get_nShowCmd (void)
+{
+ return 1;
+}
+
+#endif /* WINNT */
+#ifdef VMS
+
+/* This gets around a problem with using the old threads library on VMS 7.0. */
+
+extern long get_gmtoff (void);
+
+long
+get_gmtoff (void)
+{
+ time_t t;
+ struct tm *ts;
+
+ t = time ((time_t) 0);
+ ts = localtime (&t);
+ return ts->tm_gmtoff;
+}
+#endif
+
+/* This value is returned as the time zone offset when a valid value
+ cannot be determined. It is simply a bizarre value that will never
+ occur. It is 3 days plus 73 seconds (offset is in seconds). */
+
+long __gnat_invalid_tzoff = 259273;
+
+/* Definition of __gnat_localtime_r used by a-calend.adb */
+
+#if defined (__MINGW32__)
+
+#ifdef CERT
+
+/* For the Cert run times on native Windows we use dummy functions
+ for locking and unlocking tasks since we do not support multiple
+ threads on this configuration (Cert run time on native Windows). */
+
+void dummy (void) {}
+
+void (*Lock_Task) () = &dummy;
+void (*Unlock_Task) () = &dummy;
+
+#else
+
+#define Lock_Task system__soft_links__lock_task
+extern void (*Lock_Task) (void);
+
+#define Unlock_Task system__soft_links__unlock_task
+extern void (*Unlock_Task) (void);
+
+#endif
+
+/* Reentrant localtime for Windows. */
+
+extern void
+__gnat_localtime_tzoff (const time_t *, const int *, long *);
+
+static const unsigned long long w32_epoch_offset = 11644473600ULL;
+void
+__gnat_localtime_tzoff (const time_t *timer, const int *is_historic, long *off)
+{
+ TIME_ZONE_INFORMATION tzi;
+
+ BOOL rtx_active;
+ DWORD tzi_status;
+
+#ifdef RTX
+ rtx_active = 1;
+#else
+ rtx_active = 0;
+#endif
+
+ (*Lock_Task) ();
+
+ tzi_status = GetTimeZoneInformation (&tzi);
+
+ /* Processing for RTX targets or cases where we simply want to extract the
+ offset of the current time zone, regardless of the date. A value of "0"
+ for flag "is_historic" signifies that the date is NOT historic, see the
+ body of Ada.Calendar.UTC_Time_Offset. */
+
+ if (rtx_active || *is_historic == 0) {
+ *off = tzi.Bias;
+
+ /* The system is operating in the range covered by the StandardDate
+ member. */
+ if (tzi_status == TIME_ZONE_ID_STANDARD) {
+ *off = *off + tzi.StandardBias;
+ }
+
+ /* The system is operating in the range covered by the DaylightDate
+ member. */
+ else if (tzi_status == TIME_ZONE_ID_DAYLIGHT) {
+ *off = *off + tzi.DaylightBias;
+ }
+
+ *off = *off * -60;
+ }
+
+ /* Time zone offset calculations for a historic or future date */
+
+ else {
+ union
+ {
+ FILETIME ft_time;
+ unsigned long long ull_time;
+ } utc_time, local_time;
+
+ SYSTEMTIME utc_sys_time, local_sys_time;
+ BOOL status;
+
+ /* First convert unix time_t structure to windows FILETIME format. */
+ utc_time.ull_time = ((unsigned long long) *timer + w32_epoch_offset)
+ * 10000000ULL;
+
+ /* If GetTimeZoneInformation does not return a value between 0 and 2 then
+ it means that we were not able to retrieve timezone informations. Note
+ that we cannot use here FileTimeToLocalFileTime as Windows will use in
+ always in this case the current timezone setting. As suggested on MSDN
+ we use the following three system calls to get the right information.
+ Note also that starting with Windows Vista new functions are provided
+ to get timezone settings that depend on the year. We cannot use them as
+ we still support Windows XP and Windows 2003. */
+
+ status = (tzi_status >= 0 && tzi_status <= 2)
+ && FileTimeToSystemTime (&utc_time.ft_time, &utc_sys_time)
+ && SystemTimeToTzSpecificLocalTime (&tzi, &utc_sys_time, &local_sys_time)
+ && SystemTimeToFileTime (&local_sys_time, &local_time.ft_time);
+
+ /* An error has occured, return invalid_tzoff */
+
+ if (!status) {
+ *off = __gnat_invalid_tzoff;
+ }
+ else {
+ if (local_time.ull_time > utc_time.ull_time) {
+ *off = (long) ((local_time.ull_time - utc_time.ull_time)
+ / 10000000ULL);
+ }
+ else {
+ *off = - (long) ((utc_time.ull_time - local_time.ull_time)
+ / 10000000ULL);
+ }
+ }
+ }
+
+ (*Unlock_Task) ();
+}
+
+#else
+
+/* On Lynx, all time values are treated in GMT */
+
+#if defined (__Lynx__)
+
+/* As of LynxOS 3.1.0a patch level 040, LynuxWorks changes the
+ prototype to the C library function localtime_r from the POSIX.4
+ Draft 9 to the POSIX 1.c version. Before this change the following
+ spec is required. Only use when ___THREADS_POSIX4ad4__ is defined,
+ the Lynx convention when building against the legacy API. */
+
+extern void
+__gnat_localtime_tzoff (const time_t *, const int *, long *);
+
+void
+__gnat_localtime_tzoff (const time_t *timer, const int *is_historic, long *off)
+{
+ *off = 0;
+}
+
+#else
+
+/* VMS does not need __gnat_localtime_tzoff */
+
+#if defined (VMS)
+
+/* Other targets except Lynx, VMS and Windows provide a standard localtime_r */
+
+#else
+
+#define Lock_Task system__soft_links__lock_task
+extern void (*Lock_Task) (void);
+
+#define Unlock_Task system__soft_links__unlock_task
+extern void (*Unlock_Task) (void);
+
+extern void
+__gnat_localtime_tzoff (const time_t *, const int *, long *);
+
+void
+__gnat_localtime_tzoff (const time_t *timer, const int *is_historic, long *off)
+{
+ struct tm tp;
+
+/* AIX, HPUX, Sun Solaris */
+#if defined (_AIX) || defined (__hpux__) || defined (sun)
+{
+ (*Lock_Task) ();
+
+ localtime_r (timer, &tp);
+ *off = (long) -timezone;
+
+ (*Unlock_Task) ();
+
+ /* Correct the offset if Daylight Saving Time is in effect */
+
+ if (tp.tm_isdst > 0)
+ *off = *off + 3600;
+}
+
+/* VxWorks */
+#elif defined (__vxworks)
+#include <stdlib.h>
+{
+ (*Lock_Task) ();
+
+ localtime_r (timer, &tp);
+
+ /* Try to read the environment variable TIMEZONE. The variable may not have
+ been initialize, in that case return an offset of zero (0) for UTC. */
+
+ char *tz_str = getenv ("TIMEZONE");
+
+ if ((tz_str == NULL) || (*tz_str == '\0'))
+ *off = 0;
+ else
+ {
+ char *tz_start, *tz_end;
+
+ /* The format of the data contained in TIMEZONE is N::U:S:E where N is the
+ name of the time zone, U are the minutes difference from UTC, S is the
+ start of DST in mmddhh and E is the end of DST in mmddhh. Extracting
+ the value of U involves setting two pointers, one at the beginning and
+ one at the end of the value. The end pointer is then set to null in
+ order to delimit a string slice for atol to process. */
+
+ tz_start = index (tz_str, ':') + 2;
+ tz_end = index (tz_start, ':');
+ tz_end = '\0';
+
+ /* The Ada layer expects an offset in seconds. Note that we must reverse
+ the sign of the result since west is positive and east is negative on
+ VxWorks targets. */
+
+ *off = -atol (tz_start) * 60;
+
+ /* Correct the offset if Daylight Saving Time is in effect */
+
+ if (tp.tm_isdst > 0)
+ *off = *off + 3600;
+ }
+
+ (*Unlock_Task) ();
+}
+
+/* Darwin, Free BSD, Linux, where component tm_gmtoff is present in
+ struct tm */
+
+#elif defined (__APPLE__) || defined (__FreeBSD__) || defined (linux) ||\
+ defined (__GLIBC__)
+{
+ localtime_r (timer, &tp);
+ *off = tp.tm_gmtoff;
+}
+
+/* Default: treat all time values in GMT */
+
+#else
+ *off = 0;
+
+#endif
+}
+
+#endif
+#endif
+#endif
+
+#ifdef __vxworks
+
+#include <taskLib.h>
+
+/* __gnat_get_task_options is used by s-taprop.adb only for VxWorks. This
+ function returns the options to be set when creating a new task. It fetches
+ the options assigned to the current task (parent), so offering some user
+ level control over the options for a task hierarchy. It forces VX_FP_TASK
+ because it is almost always required. On processors with the SPE
+ category, VX_SPE_TASK should be used instead to enable the SPE. */
+extern int __gnat_get_task_options (void);
+
+int
+__gnat_get_task_options (void)
+{
+ int options;
+
+ /* Get the options for the task creator */
+ taskOptionsGet (taskIdSelf (), &options);
+
+ /* Force VX_FP_TASK or VX_SPE_TASK as needed */
+#if defined (__SPE__)
+ options |= VX_SPE_TASK;
+#else
+ options |= VX_FP_TASK;
+#endif
+
+ /* Mask those bits that are not under user control */
+#ifdef VX_USR_TASK_OPTIONS
+ return options & VX_USR_TASK_OPTIONS;
+#else
+ return options;
+#endif
+}
+
+#endif
+
+int
+__gnat_is_file_not_found_error (int errno_val) {
+ switch (errno_val) {
+ case ENOENT:
+#ifdef __vxworks
+ /* In the case of VxWorks, we also have to take into account various
+ * filesystem-specific variants of this error.
+ */
+#if ! defined (VTHREADS)
+ case S_dosFsLib_FILE_NOT_FOUND:
+#endif
+#if ! defined (__RTP__) && (! defined (VTHREADS) || defined (__VXWORKSMILS__))
+ case S_nfsLib_NFSERR_NOENT:
+#endif
+#endif
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
+#ifdef __ANDROID__
+
+/* Provide extern symbols for sig* as needed by the tasking run-time, instead
+ of static inline functions. */
+
+#include <signal.h>
+
+int
+_sigismember (sigset_t *set, int signum)
+{
+ return sigismember (set, signum);
+}
+
+int
+_sigaddset (sigset_t *set, int signum)
+{
+ return sigaddset (set, signum);
+}
+
+int
+_sigdelset (sigset_t *set, int signum)
+{
+ return sigdelset (set, signum);
+}
+
+int
+_sigemptyset (sigset_t *set)
+{
+ return sigemptyset (set);
+}
+
+int
+_sigfillset (sigset_t *set)
+{
+ return sigfillset (set);
+}
+
+#include <unistd.h>
+int
+_getpagesize (void)
+{
+ return getpagesize ();
+}
+#endif