OSDN Git Service

2010-04-06 Matthias Klose <doko@ubuntu.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / sysdep.c
index a2804c6..5af4299 100644 (file)
@@ -6,29 +6,26 @@
  *                                                                          *
  *                          C Implementation File                           *
  *                                                                          *
- *                            $Revision$
- *                                                                          *
- *          Copyright (C) 1992-2002 Free Software Foundation, Inc.          *
+ *         Copyright (C) 1992-2009, 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 2,  or (at your option) any later ver- *
+ * 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.  See the GNU General Public License *
- * for  more details.  You should have  received  a copy of the GNU General *
- * Public License  distributed with GNAT;  see file COPYING.  If not, write *
- * to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, *
- * MA 02111-1307, USA.                                                      *
+ * 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.               *
  *                                                                          *
- * As a  special  exception,  if you  link  this file  with other  files to *
- * produce an executable,  this file does not by itself cause the resulting *
- * executable to be covered by the GNU General Public License. This except- *
- * ion does not  however invalidate  any other reasons  why the  executable *
- * file might be covered by the  GNU Public License.                        *
+ * 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. *
- * It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). *
+ * Extensive contributions were provided by Ada Core Technologies Inc.      *
  *                                                                          *
  ****************************************************************************/
 
 
 #ifdef __vxworks
 #include "ioLib.h"
+#if ! defined (__VXWORKSMILS__)
+#include "dosFsLib.h"
+#endif
+#if ! defined (__RTP__) && (! defined (VTHREADS) || defined (__VXWORKSMILS__))
+# include "nfsLib.h"
+#endif
 #include "selectLib.h"
 #include "vxWorks.h"
 #endif
+
 #ifdef IN_RTS
 #define POSIX
 #include "tconfig.h"
 #include "tsystem.h"
 #include <fcntl.h>
 #include <sys/stat.h>
-#include "time.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"
 
 /*
@@ -159,15 +174,13 @@ static const char *mode_append_binary_plus = "a+b";
 const char __gnat_text_translation_required = 1;
 
 void
-__gnat_set_binary_mode (handle)
-     int handle;
+__gnat_set_binary_mode (int handle)
 {
   _setmode (handle, O_BINARY);
 }
 
 void
-__gnat_set_text_mode (handle)
-     int handle;
+__gnat_set_text_mode (int handle)
 {
   _setmode (handle, O_TEXT);
 }
@@ -180,8 +193,7 @@ __gnat_set_text_mode (handle)
    "console".  */
 
 char *
-__gnat_ttyname (filedes)
-     int filedes;
+__gnat_ttyname (int filedes)
 {
   if (isatty (filedes))
     return "console";
@@ -189,7 +201,7 @@ __gnat_ttyname (filedes)
     return NULL;
 }
 
-/* This function is needed to fix a bug under Win95/98. Under these plateforms
+/* This function is needed to fix a bug under Win95/98. Under these platforms
    doing :
                 ch1 = getch();
                ch2 = fgetc (stdin);
@@ -205,26 +217,45 @@ __gnat_ttyname (filedes)
    This problem occurs when using Text_IO.Get_Line after Text_IO.Get_Immediate
    for example.
 
-   Calling FlushConsoleInputBuffer just after getch() fix the bug under 
+   Calling FlushConsoleInputBuffer just after getch() fix the bug under
    95/98. */
 
-static void winflush_init PARAMS ((void));
+#ifdef RTX
+
+static void winflush_nt (void);
+
+/* winflush_function will do nothing since we only have problems with Windows
+   95/98 which are not supported by RTX. */
+
+static void (*winflush_function) (void) = winflush_nt;
+
+static void
+winflush_nt (void)
+{
+  /* Does nothing as there is no problem under NT.  */
+}
 
-static void winflush_95 PARAMS ((void));
+#else
 
-static void winflush_nt PARAMS ((void));
+static void winflush_init (void);
+
+static void winflush_95 (void);
+
+static void winflush_nt (void);
+
+int __gnat_is_windows_xp (void);
 
 /* winflusfunction is set first to the winflushinit function which will check
    the OS version 95/98 or NT/2000 */
 
-static void (*winflush_function) PARAMS ((void)) = winflush_init;
+static void (*winflush_function) (void) = winflush_init;
 
 /* This function does the runtime check of the OS version and then sets
-   winflush_function to the appropriate function and then call it. */ 
+   winflush_function to the appropriate function and then call it. */
 
 static void
-winflush_init ()
-{ 
+winflush_init (void)
+{
   DWORD dwVersion = GetVersion();
 
   if (dwVersion < 0x80000000)                /* Windows NT/2000 */
@@ -236,15 +267,42 @@ winflush_init ()
 
 }
 
-static void winflush_95 ()
-{ 
+static void
+winflush_95 (void)
+{
   FlushConsoleInputBuffer (GetStdHandle (STD_INPUT_HANDLE));
 }
 
-static void winflush_nt ()
+static void
+winflush_nt (void)
 {
   /* Does nothing as there is no problem under NT.  */
 }
+
+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
+
 #endif
 
 #else
@@ -266,37 +324,43 @@ const char __gnat_text_translation_required = 0;
 /* These functions do nothing in non-DOS systems. */
 
 void
-__gnat_set_binary_mode (handle)
-     int handle ATTRIBUTE_UNUSED;
+__gnat_set_binary_mode (int handle ATTRIBUTE_UNUSED)
 {
 }
 
 void
-__gnat_set_text_mode (handle)
-     int handle ATTRIBUTE_UNUSED;
+__gnat_set_text_mode (int handle ATTRIBUTE_UNUSED)
 {
 }
 char *
-__gnat_ttyname (filedes)
-     int filedes;
+__gnat_ttyname (int filedes)
 {
-#ifndef __vxworks
-  extern char *ttyname PARAMS ((int));
-
-  return ttyname (filedes);
-
-#else
+#if defined (__vxworks) || defined (__nucleus)
   return "";
+#else
+  extern char *ttyname (int);
 
-#endif
+  return ttyname (filedes);
+#endif /* defined (__vxworks) || defined (__nucleus) */
 }
 #endif
 \f
 #if defined (linux) || defined (sun) || defined (sgi) || defined (__EMX__) \
   || (defined (__osf__) && ! defined (__alpha_vxworks)) || defined (WINNT) \
-  || defined (__MACHTEN__) || defined (hpux) || defined (_AIX) \
-  || (defined (__svr4__) && defined (i386)) || defined (__Lynx__)
+  || 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)
@@ -308,18 +372,14 @@ static int initted = 0;
 /* Implements the common processing for getc_immediate and
    getc_immediate_nowait. */
 
-extern void getc_immediate             PARAMS ((FILE *, int *, int *));
-extern void getc_immediate_nowait      PARAMS ((FILE *, int *, int *, int *));
-extern void getc_immediate_common      PARAMS ((FILE *, int *, int *,
-                                                int *, int));
+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 (stream, ch, end_of_file)
-     FILE *stream;
-     int *ch;
-     int *end_of_file;
+getc_immediate (FILE *stream, int *ch, int *end_of_file)
 {
   int avail;
 
@@ -329,11 +389,7 @@ getc_immediate (stream, ch, end_of_file)
 /* Called by Get_Immediate (Foo, Available); */
 
 void
-getc_immediate_nowait (stream, ch, end_of_file, avail)
-     FILE *stream;
-     int *ch;
-     int *end_of_file;
-     int *avail;
+getc_immediate_nowait (FILE *stream, int *ch, int *end_of_file, int *avail)
 {
   getc_immediate_common (stream, ch, end_of_file, avail, 0);
 }
@@ -341,18 +397,18 @@ getc_immediate_nowait (stream, ch, end_of_file, avail)
 /* Called by getc_immediate () and getc_immediate_nowait () */
 
 void
-getc_immediate_common (stream, ch, end_of_file, avail, waiting)
-     FILE *stream;
-     int *ch;
-     int *end_of_file;
-     int *avail;
-     int waiting;
+getc_immediate_common (FILE *stream,
+                       int *ch,
+                       int *end_of_file,
+                       int *avail,
+                       int waiting)
 {
 #if defined (linux) || defined (sun) || defined (sgi) || defined (__EMX__) \
     || (defined (__osf__) && ! defined (__alpha_vxworks)) \
-    || defined (__CYGWIN32__) || defined (__MACHTEN__) || defined (hpux) \
+    || defined (__CYGWIN32__) || defined (__MACHTEN__) || defined (__hpux__) \
     || defined (_AIX) || (defined (__svr4__) && defined (i386)) \
-    || defined (__Lynx__)
+    || defined (__Lynx__) || defined (__FreeBSD__) || defined (__OpenBSD__) \
+    || defined (__GLIBC__) || defined (__APPLE__)
   char c;
   int nread;
   int good_one = 0;
@@ -369,9 +425,10 @@ getc_immediate_common (stream, ch, end_of_file, avail, waiting)
       termios_rec.c_lflag = termios_rec.c_lflag & ~ICANON & ~ECHO;
 
 #if defined(linux) || defined (sun) || defined (sgi) || defined (__EMX__) \
-    || defined (__osf__) || defined (__MACHTEN__) || defined (hpux) \
+    || defined (__osf__) || defined (__MACHTEN__) || defined (__hpux__) \
     || defined (_AIX) || (defined (__svr4__) && defined (i386)) \
-    || defined (__Lynx__)
+    || 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
@@ -498,7 +555,7 @@ getc_immediate_common (stream, ch, end_of_file, avail, waiting)
 #elif defined (__vxworks)
   /* Bit masks of file descriptors to read from.  */
   struct fd_set readFds;
-  /* Timeout before select returns if nothing can be read.  */ 
+  /* Timeout before select returns if nothing can be read.  */
   struct timeval timeOut;
   char c;
   int fd = fileno (stream);
@@ -508,14 +565,14 @@ getc_immediate_common (stream, ch, end_of_file, avail, waiting)
   int status;
   int width;
 
-  if (isatty (fd)) 
+  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) 
+      if (! waiting)
        {
          /* Initialization of timeOut for its use with select.  */
          timeOut.tv_sec  = 0;
@@ -537,19 +594,19 @@ getc_immediate_common (stream, ch, end_of_file, avail, waiting)
          else
            {
              nread = read (fd, &c, 1);
-             if (nread > 0) 
+             if (nread > 0)
                *avail = 1, *end_of_file = 0;
              /* End Of File. */
-             else if (nread == 0) 
+             else if (nread == 0)
                *avail = 0, *end_of_file = 1;
              /* Error.  */
-             else 
+             else
                *avail = -1, *end_of_file = -1;
-           }   
+           }
        }
 
       /* We have to wait until we get a character */
-      else 
+      else
        {
          *avail = -1;
          *end_of_file = -1;
@@ -559,13 +616,13 @@ getc_immediate_common (stream, ch, end_of_file, avail, waiting)
 
          /* Set FD in RAW mode.  */
          status = ioctl (fd, FIOSETOPTIONS, OPT_RAW);
-         if (status != -1) 
+         if (status != -1)
            {
              nread = read (fd, &c, 1);
-             if (nread > 0) 
+             if (nread > 0)
                *avail = 1, *end_of_file = 0;
              /* End of file.  */
-             else if (nread == 0) 
+             else if (nread == 0)
                *avail = 0, *end_of_file = 1;
              /* Else there is an ERROR.  */
            }
@@ -607,33 +664,33 @@ getc_immediate_common (stream, ch, end_of_file, avail, waiting)
    will want to import these).  We use the same names as the routines used
    by AdaMagic for compatibility.  */
 
-char *rts_get_hInstance     PARAMS ((void));
-char *rts_get_hPrevInstance PARAMS ((void));
-char *rts_get_lpCommandLine PARAMS ((void));
-int   rts_get_nShowCmd      PARAMS ((void));
+char *rts_get_hInstance (void);
+char *rts_get_hPrevInstance (void);
+char *rts_get_lpCommandLine (void);
+int   rts_get_nShowCmd (void);
 
 char *
-rts_get_hInstance (
-{ 
-  return GetModuleHandleA (0); 
+rts_get_hInstance (void)
+{
+  return (char *)GetModuleHandleA (0);
 }
 
 char *
-rts_get_hPrevInstance (
-{ 
-  return 0; 
+rts_get_hPrevInstance (void)
+{
+  return 0;
 }
 
 char *
-rts_get_lpCommandLine (
-{ 
-  return GetCommandLineA (); 
+rts_get_lpCommandLine (void)
+{
+  return GetCommandLineA ();
 }
 
-int   
-rts_get_nShowCmd (
-{ 
-  return 1; 
+int
+rts_get_nShowCmd (void)
+{
+  return 1;
 }
 
 #endif /* WINNT */
@@ -641,12 +698,10 @@ rts_get_nShowCmd ()
 
 /* This gets around a problem with using the old threads library on VMS 7.0. */
 
-#include <time.h>
-
-extern long get_gmtoff PARAMS ((void));
+extern long get_gmtoff (void);
 
 long
-get_gmtoff ()
+get_gmtoff (void)
 {
   time_t t;
   struct tm *ts;
@@ -657,38 +712,114 @@ get_gmtoff ()
 }
 #endif
 
-/* Definition of __gnat_locatime_r used by a-calend.adb */
+/* 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 (__EMX__) || 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
 
-#if defined (_AIX) || defined (__EMX__)
 #define Lock_Task system__soft_links__lock_task
-extern void (*Lock_Task) PARAMS ((void));
+extern void (*Lock_Task) (void);
 
 #define Unlock_Task system__soft_links__unlock_task
-extern void (*Unlock_Task) PARAMS ((void));
+extern void (*Unlock_Task) (void);
+
+#endif
 
-/* Provide reentrant version of localtime on Aix and OS/2. Note that AiX does
-   provide localtime_r, but in the library libc_r which doesn't get included
-   systematically, so we can't use it. */
+/* Reentrant localtime for Windows and OS/2. */
 
-extern void struct tm *__gnat_localtime_r PARAMS ((const time_t *,
-                                                  struct tm *));
+extern void
+__gnat_localtime_tzoff (const time_t *, long *);
 
-struct tm *
-__gnat_localtime_r (timer, tp)
-     const time_t *timer;
-     struct tm *tp;
+static const unsigned long long w32_epoch_offset = 11644473600ULL;
+void
+__gnat_localtime_tzoff (const time_t *timer, long *off)
 {
-  struct tm *tmp;
+  union
+  {
+    FILETIME ft_time;
+    unsigned long long ull_time;
+  } utc_time, local_time;
+
+  SYSTEMTIME utc_sys_time, local_sys_time;
+  TIME_ZONE_INFORMATION tzi;
+
+  BOOL  status = 1;
+  DWORD tzi_status;
 
   (*Lock_Task) ();
-  tmp = localtime (timer);
-  memcpy (tp, tmp, sizeof (struct tm));
+
+#ifdef RTX
+
+  tzi_status = GetTimeZoneInformation (&tzi);
+  *off = tzi.Bias;
+  if (tzi_status == TIME_ZONE_ID_STANDARD)
+     /* The system is operating in the range covered by the StandardDate
+        member. */
+     *off = *off + tzi.StandardBias;
+  else if (tzi_status == TIME_ZONE_ID_DAYLIGHT)
+     /* The system is operating in the range covered by the DaylightDate
+        member. */
+     *off = *off + tzi.DaylightBias;
+  *off = *off * -60;
+
+#else
+
+  /* First convert unix time_t structure to windows FILETIME format.  */
+  utc_time.ull_time = ((unsigned long long) *timer + w32_epoch_offset)
+                      * 10000000ULL;
+
+  tzi_status = GetTimeZoneInformation (&tzi);
+
+  /* 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);
+
+  if (!status)
+     /* An error occurs so return invalid_tzoff.  */
+     *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);
+
+#endif
+
   (*Unlock_Task) ();
-  return tp;
 }
 
 #else
-#if defined (__Lynx__) && defined (___THREADS_POSIX4ad4__)
+
+/* 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
@@ -696,35 +827,176 @@ __gnat_localtime_r (timer, tp)
    spec is required. Only use when ___THREADS_POSIX4ad4__ is defined,
    the Lynx convention when building against the legacy API. */
 
-extern struct tm *__gnat_localtime_r PARAMS ((const time_t *, struct tm *));
+extern void
+__gnat_localtime_tzoff (const time_t *, long *);
 
-struct tm *
-__gnat_localtime_r (timer, tp)
-     const time_t *timer;
-     struct tm *tp;
+void
+__gnat_localtime_tzoff (const time_t *timer, long *off)
 {
-  localtime_r (tp, timer);
-  return NULL;
+  *off = 0;
 }
 
 #else
-#if defined (VMS) || defined (__MINGW32__)
 
-/* __gnat_localtime_r is not needed on NT and VMS */
+/* VMS does not need __gnat_locatime_tzoff */
+
+#if defined (VMS)
+
+/* Other targets except Lynx, VMS and Windows provide a standard locatime_r */
 
 #else
 
-/* All other targets provide a standard localtime_r */
+#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 *, long *);
 
-extern struct tm *__gnat_localtime_r PARAMS ((const time_t *, struct tm *));
+void
+__gnat_localtime_tzoff (const time_t *timer, long *off)
+{
+  struct tm tp;
 
-struct tm *
-__gnat_localtime_r (timer, tp)
-     const time_t *timer;
-     struct tm *tp;
+/* AIX, HPUX, SGI Irix, Sun Solaris */
+#if defined (_AIX) || defined (__hpux__) || defined (sgi) || defined (sun)
 {
-  return (struct tm *) localtime_r (timer, tp);
+  (*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, Tru64, where component tm_gmtoff is present in
+   struct tm */
+
+#elif defined (__APPLE__) || defined (__FreeBSD__) || defined (linux) ||\
+     (defined (__alpha__) && defined (__osf__)) || 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 is needed 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 because it is almost always required */
+  options |= VX_FP_TASK;
+#if defined (__SPE__)
+  options |= VX_SPE_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 (__VXWORKSMILS__)
+      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;
+   }
+}