OSDN Git Service

* config/vax/vax.h (target_flags, MASK_UNIX_ASM, MASK_VAXC_ALIGNMENT)
[pf3gnuchains/gcc-fork.git] / gcc / ada / adaint.c
index c169ec8..6d65efd 100644 (file)
@@ -4,11 +4,9 @@
  *                                                                          *
  *                               A D A I N T                                *
  *                                                                          *
- *                            $Revision$
- *                                                                          *
  *                          C Implementation File                           *
  *                                                                          *
- *          Copyright (C) 1992-2001, Free Software Foundation, Inc.         *
+ *          Copyright (C) 1992-2005, 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- *
  * file might be covered by the  GNU Public License.                        *
  *                                                                          *
  * 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.      *
  *                                                                          *
  ****************************************************************************/
 
-/*  This file contains those routines named by Import pragmas in packages   */
-/*  in the GNAT hierarchy (especially GNAT.OS_Lib) and in package Osint.    */
-/*  Many of the subprograms in OS_Lib import standard library calls         */
-/*  directly. This file contains all other routines.                        */
+/* This file contains those routines named by Import pragmas in
+   packages in the GNAT hierarchy (especially GNAT.OS_Lib) and in
+   package Osint.  Many of the subprograms in OS_Lib import standard
+   library calls directly. This file contains all other routines.  */
 
 #ifdef __vxworks
-/* No need to redefine exit here */
-#ifdef exit
+
+/* No need to redefine exit here.  */
 #undef exit
-#endif
+
 /* We want to use the POSIX variants of include files.  */
 #define POSIX
 #include "vxWorks.h"
 
 #endif /* VxWorks */
 
+#ifdef VMS
+#define _POSIX_EXIT 1
+#define HOST_EXECUTABLE_SUFFIX ".exe"
+#define HOST_OBJECT_SUFFIX ".obj"
+#endif
+
 #ifdef IN_RTS
 #include "tconfig.h"
 #include "tsystem.h"
+
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <time.h>
+#ifdef VMS
+#include <unixio.h>
+#endif
 
-/* We don't have libiberty, so us malloc.  */
+/* We don't have libiberty, so use malloc.  */
 #define xmalloc(S) malloc (S)
+#define xrealloc(V,S) realloc (V,S)
 #else
 #include "config.h"
 #include "system.h"
 #endif
+
+#ifdef __MINGW32__
+#include "mingw32.h"
+#include <sys/utime.h>
+#include <ctype.h>
+#else
+#ifndef VMS
+#include <utime.h>
+#endif
+#endif
+
+#ifdef __MINGW32__
+#if OLD_MINGW
+#include <sys/wait.h>
+#endif
+#else
 #include <sys/wait.h>
+#endif
 
 #if defined (__EMX__) || defined (MSDOS) || defined (_WIN32)
 #elif defined (VMS)
-#include <rms.h>
-#include <atrdef.h>
-#include <fibdef.h>
-#include <stsdef.h>
-#include <iodef.h>
+
+/* Header files and definitions for __gnat_set_file_time_name.  */
+
+#include <vms/rms.h>
+#include <vms/atrdef.h>
+#include <vms/fibdef.h>
+#include <vms/stsdef.h>
+#include <vms/iodef.h>
 #include <errno.h>
-#include <descrip.h>
+#include <vms/descrip.h>
 #include <string.h>
 #include <unixlib.h>
 
-struct utimbuf
-{
-  time_t actime;
-  time_t modtime;
-};
-
-#define NOREAD     0x01
-#define NOWRITE    0x02
-#define NOEXECUTE  0x04
-#define NODELETE   0x08
-
-/* use native 64-bit arithmetic */
+/* Use native 64-bit arithmetic.  */
 #define unix_time_to_vms(X,Y) \
   { unsigned long long reftime, tmptime = (X); \
     $DESCRIPTOR (unixtime,"1-JAN-1970 0:00:00.00"); \
@@ -104,21 +122,22 @@ struct dsc$descriptor_fib
   struct fibdef *fib$l_addr;
 };
 
+/* I/O Status Block.  */
 struct IOSB
-{ 
+{
   unsigned short status, count;
   unsigned long devdep;
 };
 
 static char *tryfile;
 
+/* Variable length string.  */
 struct vstring
 {
   short length;
-  char string [NAM$C_MAXRSS+1];
+  char string[NAM$C_MAXRSS+1];
 };
 
-
 #else
 #include <utime.h>
 #endif
@@ -130,6 +149,8 @@ struct vstring
 #if defined (_WIN32)
 #include <dir.h>
 #include <windows.h>
+#undef DIR_SEPARATOR
+#define DIR_SEPARATOR '\\'
 #endif
 
 #include "adaint.h"
@@ -198,12 +219,12 @@ char __gnat_path_separator = PATH_SEPARATOR;
 
    ??? This should be part of a GNAT host-specific compiler
        file instead of being included in all user applications
-       as well. This is only a temporary work-around for 3.11b. */
+       as well. This is only a temporary work-around for 3.11b.  */
 
 #ifndef GNAT_LIBRARY_TEMPLATE
-#if defined(__EMX__)
+#if defined (__EMX__)
 #define GNAT_LIBRARY_TEMPLATE "*.a"
-#elif defined(VMS)
+#elif defined (VMS)
 #define GNAT_LIBRARY_TEMPLATE "*.olb"
 #else
 #define GNAT_LIBRARY_TEMPLATE "lib*.a"
@@ -212,17 +233,95 @@ char __gnat_path_separator = PATH_SEPARATOR;
 
 const char *__gnat_library_template = GNAT_LIBRARY_TEMPLATE;
 
+/* This variable is used in hostparm.ads to say whether the host is a VMS
+   system.  */
+#ifdef VMS
+const int __gnat_vmsp = 1;
+#else
+const int __gnat_vmsp = 0;
+#endif
+
+#ifdef __EMX__
+#define GNAT_MAX_PATH_LEN MAX_PATH
+
+#elif defined (VMS)
+#define GNAT_MAX_PATH_LEN 256 /* PATH_MAX */
+
+#elif defined (__vxworks) || defined (__OPENNT)
+#define GNAT_MAX_PATH_LEN PATH_MAX
+
+#else
+
+#if defined (__MINGW32__)
+#include "mingw32.h"
+
+#if OLD_MINGW
+#include <sys/param.h>
+#endif
+
+#else
+#include <sys/param.h>
+#endif
+
+#define GNAT_MAX_PATH_LEN MAXPATHLEN
+
+#endif
+
+/* The __gnat_max_path_len variable is used to export the maximum
+   length of a path name to Ada code. max_path_len is also provided
+   for compatibility with older GNAT versions, please do not use
+   it. */
+
+int __gnat_max_path_len = GNAT_MAX_PATH_LEN;
+int max_path_len = GNAT_MAX_PATH_LEN;
+
 /* The following macro HAVE_READDIR_R should be defined if the
-   system provides the routine readdir_r */
+   system provides the routine readdir_r */
 #undef HAVE_READDIR_R
 \f
+#if defined(VMS) && defined (__LONG_POINTERS)
+
+/* Return a 32 bit pointer to an array of 32 bit pointers
+   given a 64 bit pointer to an array of 64 bit pointers */
+
+typedef __char_ptr32 *__char_ptr_char_ptr32 __attribute__ ((mode (SI)));
+
+static __char_ptr_char_ptr32
+to_ptr32 (char **ptr64)
+{
+  int argc;
+  __char_ptr_char_ptr32 short_argv;
+
+  for (argc=0; ptr64[argc]; argc++);
+
+  /* Reallocate argv with 32 bit pointers. */
+  short_argv = (__char_ptr_char_ptr32) decc$malloc
+    (sizeof (__char_ptr32) * (argc + 1));
+
+  for (argc=0; ptr64[argc]; argc++)
+    short_argv[argc] = (__char_ptr32) decc$strdup (ptr64[argc]);
+
+  short_argv[argc] = (__char_ptr32) 0;
+  return short_argv;
+
+}
+#define MAYBE_TO_PTR32(argv) to_ptr32 (argv)
+#else
+#define MAYBE_TO_PTR32(argv) argv
+#endif
+
 void
-__gnat_to_gm_time (p_time, p_year, p_month, p_day, p_hours, p_mins, p_secs)
-     time_t *p_time;
-     int *p_year, *p_month, *p_day, *p_hours, *p_mins, *p_secs;
+__gnat_to_gm_time
+  (OS_Time *p_time,
+   int *p_year,
+   int *p_month,
+   int *p_day,
+   int *p_hours,
+   int *p_mins,
+   int *p_secs)
 {
   struct tm *res;
-  time_t time = *p_time;
+  time_t time = (time_t) *p_time;
 
 #ifdef _WIN32
   /* On Windows systems, the time is sometimes rounded up to the nearest
@@ -231,7 +330,11 @@ __gnat_to_gm_time (p_time, p_year, p_month, p_day, p_hours, p_mins, p_secs)
     time++;
 #endif
 
+#ifdef VMS
+  res = localtime (&time);
+#else
   res = gmtime (&time);
+#endif
 
   if (res)
     {
@@ -241,7 +344,7 @@ __gnat_to_gm_time (p_time, p_year, p_month, p_day, p_hours, p_mins, p_secs)
       *p_hours = res->tm_hour;
       *p_mins = res->tm_min;
       *p_secs = res->tm_sec;
-  }
+    }
   else
     *p_year = *p_month = *p_day = *p_hours = *p_mins = *p_secs = 0;
 }
@@ -251,11 +354,10 @@ __gnat_to_gm_time (p_time, p_year, p_month, p_day, p_hours, p_mins, p_secs)
    of characters of its content in BUF.  Otherwise, return -1.  For Windows,
    OS/2 and vxworks, always return -1.  */
 
-int    
-__gnat_readlink (path, buf, bufsiz)
-     char *path;
-     char *buf;
-     size_t bufsiz;
+int
+__gnat_readlink (char *path ATTRIBUTE_UNUSED,
+                char *buf ATTRIBUTE_UNUSED,
+                size_t bufsiz ATTRIBUTE_UNUSED)
 {
 #if defined (MSDOS) || defined (_WIN32) || defined (__EMX__)
   return -1;
@@ -268,15 +370,13 @@ __gnat_readlink (path, buf, bufsiz)
 #endif
 }
 
-/* Creates a symbolic link named newpath
-   which contains the string oldpath.
-   If newpath exists it will NOT be overwritten.
-   For Windows, OS/2, vxworks, Interix and VMS, always retur -1. */
+/* Creates a symbolic link named NEWPATH which contains the string OLDPATH.  If
+   NEWPATH exists it will NOT be overwritten.  For Windows, OS/2, VxWorks,
+   Interix and VMS, always return -1. */
 
 int
-__gnat_symlink (oldpath, newpath)
-     char *oldpath;
-     char *newpath;
+__gnat_symlink (char *oldpath ATTRIBUTE_UNUSED,
+               char *newpath ATTRIBUTE_UNUSED)
 {
 #if defined (MSDOS) || defined (_WIN32) || defined (__EMX__)
   return -1;
@@ -289,25 +389,23 @@ __gnat_symlink (oldpath, newpath)
 #endif
 }
 
-/* Try to lock a file, return 1 if success */
+/* Try to lock a file, return 1 if success */
 
 #if defined (__vxworks) || defined (MSDOS) || defined (_WIN32)
 
 /* Version that does not use link. */
 
 int
-__gnat_try_lock (dir, file)
-     char *dir;
-     char *file;
+__gnat_try_lock (char *dir, char *file)
 {
-  char full_path [256];
+  char full_path[256];
   int fd;
 
   sprintf (full_path, "%s%c%s", dir, DIR_SEPARATOR, file);
   fd = open (full_path, O_CREAT | O_EXCL, 0600);
-  if (fd < 0) {
+  if (fd < 0)
     return 0;
-  }
+
   close (fd);
   return 1;
 }
@@ -318,11 +416,9 @@ __gnat_try_lock (dir, file)
    line problem ??? */
 
 int
-__gnat_try_lock (dir, file)
-     char *dir;
-     char *file;
+__gnat_try_lock (char *dir, char *file)
 {
-  char full_path [256];
+  char full_path[256];
   int fd;
 
   sprintf (full_path, "%s%c%s", dir, DIR_SEPARATOR, file);
@@ -335,33 +431,34 @@ __gnat_try_lock (dir, file)
 }
 
 #else
+
 /* Version using link(), more secure over NFS.  */
+/* See TN 6913-016 for discussion ??? */
 
 int
-__gnat_try_lock (dir, file)
-     char *dir;
-     char *file;
+__gnat_try_lock (char *dir, char *file)
 {
-  char full_path [256];
-  char temp_file [256];
+  char full_path[256];
+  char temp_file[256];
   struct stat stat_result;
   int fd;
 
   sprintf (full_path, "%s%c%s", dir, DIR_SEPARATOR, file);
-  sprintf (temp_file, "%s-%d-%d", dir, getpid(), getppid ());
+  sprintf (temp_file, "%s%cTMP-%ld-%ld",
+           dir, DIR_SEPARATOR, (long)getpid(), (long)getppid ());
 
-  /* Create the temporary file and write the process number */
+  /* Create the temporary file and write the process number */
   fd = open (temp_file, O_CREAT | O_WRONLY, 0600);
   if (fd < 0)
     return 0;
 
   close (fd);
 
-  /* Link it with the new file */
+  /* Link it with the new file */
   link (temp_file, full_path);
 
   /* Count the references on the old one. If we have a count of two, then
-     the link did succeed. Remove the temporary file before returning. */
+     the link did succeed. Remove the temporary file before returning.  */
   __gnat_stat (temp_file, &stat_result);
   unlink (temp_file);
   return stat_result.st_nlink == 2;
@@ -371,9 +468,9 @@ __gnat_try_lock (dir, file)
 /* Return the maximum file name length.  */
 
 int
-__gnat_get_maximum_file_name_length ()
+__gnat_get_maximum_file_name_length (void)
 {
-#if defined(MSDOS)
+#if defined (MSDOS)
   return 8;
 #elif defined (VMS)
   if (getenv ("GNAT$EXTENDED_FILE_SPECIFICATIONS"))
@@ -385,24 +482,12 @@ __gnat_get_maximum_file_name_length ()
 #endif
 }
 
-/* Return the default switch character.  */
-
-char
-__gnat_get_switch_character ()
-{
-  /* Under MSDOS, the switch character is not normally a hyphen, but this is
-     the convention DJGPP uses. Similarly under OS2, the switch character is
-     not normally a hypen, but this is the convention EMX uses. */
-
-  return '-';
-}
-
 /* Return nonzero if file names are case sensitive.  */
 
 int
-__gnat_get_file_names_case_sensitive ()
+__gnat_get_file_names_case_sensitive (void)
 {
-#if defined (__EMX__) || defined (MSDOS) || defined (VMS) || defined(WINNT)
+#if defined (__EMX__) || defined (MSDOS) || defined (VMS) || defined (WINNT)
   return 0;
 #else
   return 1;
@@ -410,7 +495,7 @@ __gnat_get_file_names_case_sensitive ()
 }
 
 char
-__gnat_get_default_identifier_character_set ()
+__gnat_get_default_identifier_character_set (void)
 {
 #if defined (__EMX__) || defined (MSDOS)
   return 'p';
@@ -419,12 +504,10 @@ __gnat_get_default_identifier_character_set ()
 #endif
 }
 
-/* Return the current working directory */
+/* Return the current working directory */
 
 void
-__gnat_get_current_dir (dir, length)
-     char *dir;
-     int *length;
+__gnat_get_current_dir (char *dir, int *length)
 {
 #ifdef VMS
    /* Force Unix style, which is what GNAT uses internally.  */
@@ -435,17 +518,18 @@ __gnat_get_current_dir (dir, length)
 
    *length = strlen (dir);
 
-   dir [*length] = DIR_SEPARATOR;
-   ++(*length);
-   dir [*length] = '\0';
+   if (dir [*length - 1] != DIR_SEPARATOR)
+     {
+       dir [*length] = DIR_SEPARATOR;
+       ++(*length);
+     }
+   dir[*length] = '\0';
 }
 
-/* Return the suffix for object files. */
+/* Return the suffix for object files.  */
 
 void
-__gnat_get_object_suffix_ptr (len, value)
-     int *len;
-     const char **value;
+__gnat_get_object_suffix_ptr (int *len, const char **value)
 {
   *value = HOST_OBJECT_SUFFIX;
 
@@ -457,12 +541,10 @@ __gnat_get_object_suffix_ptr (len, value)
   return;
 }
 
-/* Return the suffix for executable files */
+/* Return the suffix for executable files */
 
 void
-__gnat_get_executable_suffix_ptr (len, value)
-     int *len;
-     const char **value;
+__gnat_get_executable_suffix_ptr (int *len, const char **value)
 {
   *value = HOST_EXECUTABLE_SUFFIX;
   if (!*value)
@@ -474,17 +556,15 @@ __gnat_get_executable_suffix_ptr (len, value)
 }
 
 /* Return the suffix for debuggable files. Usually this is the same as the
-   executable extension. */
+   executable extension.  */
 
 void
-__gnat_get_debuggable_suffix_ptr (len, value)
-     int *len;
-     const char **value;
+__gnat_get_debuggable_suffix_ptr (int *len, const char **value)
 {
 #ifndef MSDOS
   *value = HOST_EXECUTABLE_SUFFIX;
 #else
-  /* On DOS, the extensionless COFF file is what gdb likes. */
+  /* On DOS, the extensionless COFF file is what gdb likes.  */
   *value = "";
 #endif
 
@@ -497,9 +577,7 @@ __gnat_get_debuggable_suffix_ptr (len, value)
 }
 
 int
-__gnat_open_read (path, fmode)
-     char *path;
-     int fmode;
+__gnat_open_read (char *path, int fmode)
 {
   int fd;
   int o_fmode = O_BINARY;
@@ -507,28 +585,36 @@ __gnat_open_read (path, fmode)
   if (fmode)
     o_fmode = O_TEXT;
 
-#if defined(VMS)
-  /* Optional arguments mbc,deq,fop increase read performance */
+#if defined (VMS)
+  /* Optional arguments mbc,deq,fop increase read performance */
   fd = open (path, O_RDONLY | o_fmode, 0444,
              "mbc=16", "deq=64", "fop=tef");
-#elif defined(__vxworks)
+#elif defined (__vxworks)
   fd = open (path, O_RDONLY | o_fmode, 0444);
 #else
   fd = open (path, O_RDONLY | o_fmode);
 #endif
+
   return fd < 0 ? -1 : fd;
 }
 
-#if defined (__EMX__)
+#if defined (__EMX__) || defined (__MINGW32__)
 #define PERM (S_IREAD | S_IWRITE)
+#elif defined (VMS)
+/* Excerpt from DECC C RTL Reference Manual:
+   To create files with OpenVMS RMS default protections using the UNIX
+   system-call functions umask, mkdir, creat, and open, call mkdir, creat,
+   and open with a file-protection mode argument of 0777 in a program
+   that never specifically calls umask. These default protections include
+   correctly establishing protections based on ACLs, previous versions of
+   files, and so on. */
+#define PERM 0777
 #else
 #define PERM (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
 #endif
 
 int
-__gnat_open_rw (path, fmode)
-     char *path;
-     int  fmode;
+__gnat_open_rw (char *path, int fmode)
 {
   int fd;
   int o_fmode = O_BINARY;
@@ -536,7 +622,7 @@ __gnat_open_rw (path, fmode)
   if (fmode)
     o_fmode = O_TEXT;
 
-#if defined(VMS)
+#if defined (VMS)
   fd = open (path, O_RDWR | o_fmode, PERM,
              "mbc=16", "deq=64", "fop=tef");
 #else
@@ -547,9 +633,7 @@ __gnat_open_rw (path, fmode)
 }
 
 int
-__gnat_open_create (path, fmode)
-     char *path;
-     int  fmode;
+__gnat_open_create (char *path, int fmode)
 {
   int fd;
   int o_fmode = O_BINARY;
@@ -557,7 +641,7 @@ __gnat_open_create (path, fmode)
   if (fmode)
     o_fmode = O_TEXT;
 
-#if defined(VMS)
+#if defined (VMS)
   fd = open (path, O_WRONLY | O_CREAT | O_TRUNC | o_fmode, PERM,
              "mbc=16", "deq=64", "fop=tef");
 #else
@@ -568,9 +652,22 @@ __gnat_open_create (path, fmode)
 }
 
 int
-__gnat_open_append (path, fmode)
-     char *path;
-     int  fmode;
+__gnat_create_output_file (char *path)
+{
+  int fd;
+#if defined (VMS)
+  fd = open (path, O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, PERM,
+             "rfm=stmlf", "ctx=rec", "rat=none", "rop=nlk",
+             "shr=del,get,put,upd");
+#else
+  fd = open (path, O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, PERM);
+#endif
+
+  return fd < 0 ? -1 : fd;
+}
+
+int
+__gnat_open_append (char *path, int fmode)
 {
   int fd;
   int o_fmode = O_BINARY;
@@ -578,7 +675,7 @@ __gnat_open_append (path, fmode)
   if (fmode)
     o_fmode = O_TEXT;
 
-#if defined(VMS)
+#if defined (VMS)
   fd = open (path, O_WRONLY | O_CREAT | O_APPEND | o_fmode, PERM,
              "mbc=16", "deq=64", "fop=tef");
 #else
@@ -588,12 +685,10 @@ __gnat_open_append (path, fmode)
   return fd < 0 ? -1 : fd;
 }
 
-/*  Open a new file.  Return error (-1) if the file already exists. */
+/*  Open a new file.  Return error (-1) if the file already exists.  */
 
 int
-__gnat_open_new (path, fmode)
-     char *path;
-     int fmode;
+__gnat_open_new (char *path, int fmode)
 {
   int fd;
   int o_fmode = O_BINARY;
@@ -601,7 +696,7 @@ __gnat_open_new (path, fmode)
   if (fmode)
     o_fmode = O_TEXT;
 
-#if defined(VMS)
+#if defined (VMS)
   fd = open (path, O_WRONLY | O_CREAT | O_EXCL | o_fmode, PERM,
              "mbc=16", "deq=64", "fop=tef");
 #else
@@ -612,23 +707,21 @@ __gnat_open_new (path, fmode)
 }
 
 /* Open a new temp file.  Return error (-1) if the file already exists.
-   Special options for VMS allow the file to be shared between parent and
-   child processes, however they really slow down output.  Used in
-   gnatchop. */
+   Special options for VMS allow the file to be shared between parent and child
+   processes, however they really slow down output.  Used in gnatchop.  */
 
 int
-__gnat_open_new_temp (path, fmode)
-     char *path;
-     int fmode;
+__gnat_open_new_temp (char *path, int fmode)
 {
   int fd;
   int o_fmode = O_BINARY;
 
   strcpy (path, "GNAT-XXXXXX");
 
-#if defined (linux) && !defined (__vxworks)
+#if (defined (__FreeBSD__) || defined (linux)) && !defined (__vxworks)
   return mkstemp (path);
-
+#elif defined (__Lynx__)
+  mktemp (path);
 #else
   if (mktemp (path) == NULL)
     return -1;
@@ -637,7 +730,7 @@ __gnat_open_new_temp (path, fmode)
   if (fmode)
     o_fmode = O_TEXT;
 
-#if defined(VMS)
+#if defined (VMS)
   fd = open (path, O_WRONLY | O_CREAT | O_EXCL | o_fmode, PERM,
              "rfm=stmlf", "ctx=rec", "rat=none", "shr=del,get,put,upd",
              "mbc=16", "deq=64", "fop=tef");
@@ -648,34 +741,30 @@ __gnat_open_new_temp (path, fmode)
   return fd < 0 ? -1 : fd;
 }
 
-int
-__gnat_mkdir (dir_name)
-     char *dir_name;
-{
-  /* On some systems, mkdir has two args and on some it has one.  If we
-     are being built as part of the compiler, autoconf has figured that out
-     for us.  Otherwise, we have to do it ourselves.  */
-#ifndef IN_RTS
-  return mkdir (dir_name, S_IRWXU | S_IRWXG | S_IRWXO);
-#else
-#if defined (_WIN32) || defined (__vxworks)
-  return mkdir (dir_name);
-#else
-  return mkdir (dir_name, S_IRWXU | S_IRWXG | S_IRWXO);
-#endif
-#endif
+/* Return the number of bytes in the specified file.  */
+
+long
+__gnat_file_length (int fd)
+{
+  int ret;
+  struct stat statbuf;
+
+  ret = fstat (fd, &statbuf);
+  if (ret || !S_ISREG (statbuf.st_mode))
+    return 0;
+
+  return (statbuf.st_size);
 }
 
-/* Return the number of bytes in the specified file. */
+/* Return the number of bytes in the specified named file.  */
 
 long
-__gnat_file_length (fd)
-     int fd;
+__gnat_named_file_length (char *name)
 {
   int ret;
   struct stat statbuf;
 
-  ret = fstat (fd, &statbuf);
+  ret = __gnat_stat (name, &statbuf);
   if (ret || !S_ISREG (statbuf.st_mode))
     return 0;
 
@@ -683,11 +772,10 @@ __gnat_file_length (fd)
 }
 
 /* Create a temporary filename and put it in string pointed to by
-   tmp_filename */
+   TMP_FILENAME.  */
 
 void
-__gnat_tmp_name (tmp_filename)
-     char *tmp_filename;
+__gnat_tmp_name (char *tmp_filename)
 {
 #ifdef __MINGW32__
   {
@@ -700,10 +788,16 @@ __gnat_tmp_name (tmp_filename)
 
     pname = (char *) tempnam ("c:\\temp", "gnat-");
 
-    /* if pname start with a back slash and not path information it means that
-       the filename is valid for the current working directory */
+    /* if pname is NULL, the file was not created properly, the disk is full
+       or there is no more free temporary files */
 
-    if (pname[0] == '\\')
+    if (pname == NULL)
+      *tmp_filename = '\0';
+
+    /* If pname start with a back slash and not path information it means that
+       the filename is valid for the current working directory.  */
+
+    else if (pname[0] == '\\')
       {
        strcpy (tmp_filename, ".\\");
        strcat (tmp_filename, pname+1);
@@ -713,10 +807,14 @@ __gnat_tmp_name (tmp_filename)
 
     free (pname);
   }
-#elif defined (linux)
+
+#elif defined (linux) || defined (__FreeBSD__)
+#define MAX_SAFE_PATH 1000
   char *tmpdir = getenv ("TMPDIR");
 
-  if (tmpdir == NULL)
+  /* If tmpdir is longer than MAX_SAFE_PATH, revert to default value to avoid
+     a buffer overflow.  */
+  if (tmpdir == NULL || strlen (tmpdir) > MAX_SAFE_PATH)
     strcpy (tmp_filename, "/tmp/gnat-XXXXXX");
   else
     sprintf (tmp_filename, "%s/gnat-XXXXXX", tmpdir);
@@ -731,9 +829,7 @@ __gnat_tmp_name (tmp_filename)
    in the buffer.  */
 
 char *
-__gnat_readdir (dirp, buffer)
-     DIR *dirp;
-     char* buffer;
+__gnat_readdir (DIR *dirp, char *buffer)
 {
   /* If possible, try to use the thread-safe version.  */
 #ifdef HAVE_READDIR_R
@@ -743,7 +839,7 @@ __gnat_readdir (dirp, buffer)
     return NULL;
 
 #else
-  struct dirent *dirent = readdir (dirp);
+  struct dirent *dirent = (struct dirent *) readdir (dirp);
 
   if (dirent != NULL)
     {
@@ -759,7 +855,7 @@ __gnat_readdir (dirp, buffer)
 /* Returns 1 if readdir is thread safe, 0 otherwise.  */
 
 int
-__gnat_readdir_is_thread_safe ()
+__gnat_readdir_is_thread_safe (void)
 {
 #ifdef HAVE_READDIR_R
   return 1;
@@ -769,6 +865,8 @@ __gnat_readdir_is_thread_safe ()
 }
 
 #ifdef _WIN32
+/* Number of seconds between <Jan 1st 1601> and <Jan 1st 1970>.  */
+static const unsigned long long w32_epoch_offset = 11644473600ULL;
 
 /* Returns the file modification timestamp using Win32 routines which are
    immune against daylight saving time change. It is in fact not possible to
@@ -776,76 +874,73 @@ __gnat_readdir_is_thread_safe ()
    stat structure.  */
 
 static time_t
-win32_filetime (h)
-     HANDLE h;
+win32_filetime (HANDLE h)
 {
-  BOOL res;
-  FILETIME t_create;
-  FILETIME t_access;
-  FILETIME t_write;
-  unsigned long long timestamp;
-
-  /* Number of seconds between <Jan 1st 1601> and <Jan 1st 1970> */
-  unsigned long long offset = 11644473600;
+  union
+  {
+    FILETIME ft_time;
+    unsigned long long ull_time;
+  } t_write;
 
   /* GetFileTime returns FILETIME data which are the number of 100 nanosecs
      since <Jan 1st 1601>. This function must return the number of seconds
      since <Jan 1st 1970>.  */
 
-  res = GetFileTime (h, &t_create, &t_access, &t_write);
-
-  timestamp = (((long long) t_write.dwHighDateTime << 32) 
-              + t_write.dwLowDateTime);
-
-  timestamp = timestamp / 10000000 - offset;
-
-  return (time_t) timestamp;
+  if (GetFileTime (h, NULL, NULL, &t_write.ft_time))
+    return (time_t) (t_write.ull_time / 10000000ULL
+                    - w32_epoch_offset);
+  return (time_t) 0;
 }
 #endif
 
 /* Return a GNAT time stamp given a file name.  */
 
-time_t
-__gnat_file_time_name (name)
-     char *name;
+OS_Time
+__gnat_file_time_name (char *name)
 {
-  struct stat statbuf;
 
 #if defined (__EMX__) || defined (MSDOS)
   int fd = open (name, O_RDONLY | O_BINARY);
   time_t ret = __gnat_file_time_fd (fd);
   close (fd);
-  return ret;
+  return (OS_Time)ret;
 
 #elif defined (_WIN32)
+  time_t ret = 0;
   HANDLE h = CreateFile (name, GENERIC_READ, FILE_SHARE_READ, 0,
                         OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
-  time_t ret = win32_filetime (h);
-  CloseHandle (h);
-  return ret;
-#else
 
-  (void) __gnat_stat (name, &statbuf);
+  if (h != INVALID_HANDLE_VALUE)
+    {
+      ret = win32_filetime (h);
+      CloseHandle (h);
+    }
+  return (OS_Time) ret;
+#else
+  struct stat statbuf;
+  if (__gnat_stat (name, &statbuf) != 0) {
+     return (OS_Time)-1;
+  } else {
 #ifdef VMS
-  /* VMS has file versioning */
-  return statbuf.st_ctime;
+     /* VMS has file versioning.  */
+     return (OS_Time)statbuf.st_ctime;
 #else
-  return statbuf.st_mtime;
+     return (OS_Time)statbuf.st_mtime;
 #endif
+  }
 #endif
 }
 
 /* Return a GNAT time stamp given a file descriptor.  */
 
-time_t
-__gnat_file_time_fd (fd)
-     int fd;
+OS_Time
+__gnat_file_time_fd (int fd)
 {
   /* The following workaround code is due to the fact that under EMX and
      DJGPP fstat attempts to convert time values to GMT rather than keep the
      actual OS timestamp of the file. By using the OS2/DOS functions directly
      the GNAT timestamp are independent of this behavior, which is desired to
-     facilitate the distribution of GNAT compiled libraries. */
+     facilitate the distribution of GNAT compiled libraries.  */
 
 #if defined (__EMX__) || defined (MSDOS)
 #ifdef __EMX__
@@ -877,10 +972,10 @@ __gnat_file_time_fd (fd)
      the whole days passed.  The value for years returned by the DOS and OS2
      functions count years from 1980, so to compensate for the UNIX epoch which
      begins in 1970 start with 10 years worth of days and add days for each
-     four year period since then. */
+     four year period since then.  */
 
   time_t tot_secs;
-  int cum_days [12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
+  int cum_days[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
   int days_passed = 3652 + (file_year / 4) * 1461;
   int years_since_leap = file_year % 4;
 
@@ -894,49 +989,71 @@ __gnat_file_time_fd (fd)
   if (file_year > 20)
     days_passed -= 1;
 
-  days_passed += cum_days [file_month - 1];
+  days_passed += cum_days[file_month - 1];
   if (years_since_leap == 0 && file_year != 20 && file_month > 2)
     days_passed++;
 
   days_passed += file_day - 1;
 
-  /* OK - have whole days.  Multiply -- then add in other parts. */
+  /* OK - have whole days.  Multiply -- then add in other parts.  */
 
   tot_secs  = days_passed * 86400;
   tot_secs += file_hour * 3600;
   tot_secs += file_min * 60;
   tot_secs += file_tsec * 2;
-  return tot_secs;
+  return (OS_Time) tot_secs;
 
 #elif defined (_WIN32)
   HANDLE h = (HANDLE) _get_osfhandle (fd);
   time_t ret = win32_filetime (h);
-  CloseHandle (h);
-  return ret;
+  return (OS_Time) ret;
 
 #else
   struct stat statbuf;
 
-  (void) fstat (fd, &statbuf);
-
+  if (fstat (fd, &statbuf) != 0) {
+     return (OS_Time) -1;
+  } else {
 #ifdef VMS
-  /* VMS has file versioning */
-  return statbuf.st_ctime;
+     /* VMS has file versioning.  */
+     return (OS_Time) statbuf.st_ctime;
 #else
-  return statbuf.st_mtime;
+     return (OS_Time) statbuf.st_mtime;
 #endif
+  }
 #endif
 }
 
-/* Set the file time stamp */
+/* Set the file time stamp */
 
 void
-__gnat_set_file_time_name (name, time_stamp)
-     char *name;
-     time_t time_stamp;
+__gnat_set_file_time_name (char *name, time_t time_stamp)
 {
-#if defined (__EMX__) || defined (MSDOS) || defined (_WIN32) \
-    || defined (__vxworks)
+#if defined (__EMX__) || defined (MSDOS) || defined (__vxworks)
+
+/* Code to implement __gnat_set_file_time_name for these systems.  */
+
+#elif defined (_WIN32)
+  union
+  {
+    FILETIME ft_time;
+    unsigned long long ull_time;
+  } t_write;
+
+  HANDLE h  = CreateFile (name, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
+                         OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS,
+                         NULL);
+  if (h == INVALID_HANDLE_VALUE)
+    return;
+  /* Add number of seconds between <Jan 1st 1601> and <Jan 1st 1970> */
+  t_write.ull_time = ((unsigned long long)time_stamp + w32_epoch_offset);
+  /*  Convert to 100 nanosecond units  */
+  t_write.ull_time *= 10000000ULL;
+
+  SetFileTime(h, NULL, NULL, &t_write.ft_time);
+  CloseHandle (h);
+  return;
+
 #elif defined (VMS)
   struct FAB fab;
   struct NAM nam;
@@ -956,15 +1073,15 @@ __gnat_set_file_time_name (name, time_stamp)
              unsigned world  : 4;
            } bits;
        } prot;
-    } Fat = { 0 };
+    } Fat = { 0, 0, 0, 0, 0, { 0 }};
 
-  ATRDEF atrlst []
+  ATRDEF atrlst[]
     = {
       { ATR$S_CREDATE,  ATR$C_CREDATE,  &Fat.create },
       { ATR$S_REVDATE,  ATR$C_REVDATE,  &Fat.revise },
       { ATR$S_EXPDATE,  ATR$C_EXPDATE,  &Fat.expire },
       { ATR$S_BAKDATE,  ATR$C_BAKDATE,  &Fat.backup },
-      n{ ATR$S_FPRO,     ATR$C_FPRO,     &Fat.prot },
+      { ATR$S_FPRO,     ATR$C_FPRO,     &Fat.prot },
       { ATR$S_UIC,      ATR$C_UIC,      &Fat.uic },
       { 0, 0, 0}
     };
@@ -994,7 +1111,7 @@ __gnat_set_file_time_name (name, time_stamp)
 
   tryfile = (char *) __gnat_to_host_dir_spec (name, 0);
 
-  /* Allocate and initialize a fab and nam structures. */
+  /* Allocate and initialize a FAB and NAM structures.  */
   fab = cc$rms_fab;
   nam = cc$rms_nam;
 
@@ -1006,22 +1123,22 @@ __gnat_set_file_time_name (name, time_stamp)
   fab.fab$b_fns = strlen (tryfile);
   fab.fab$l_nam = &nam;
 
-  /*Validate filespec syntax and device existence.  */
+  /* Validate filespec syntax and device existence.  */
   status = SYS$PARSE (&fab, 0, 0);
   if ((status & 1) != 1)
     LIB$SIGNAL (status);
 
-  file.string [nam.nam$b_esl] = 0;
+  file.string[nam.nam$b_esl] = 0;
 
-  /* Find matching filespec. */
+  /* Find matching filespec.  */
   status = SYS$SEARCH (&fab, 0, 0);
   if ((status & 1) != 1)
     LIB$SIGNAL (status);
 
-  file.string [nam.nam$b_esl] = 0;
-  result.string [result.length=nam.nam$b_rsl] = 0;
+  file.string[nam.nam$b_esl] = 0;
+  result.string[result.length=nam.nam$b_rsl] = 0;
 
-  /* Get the device name and assign an IO channel. */
+  /* Get the device name and assign an IO channel.  */
   strncpy (device.string, nam.nam$l_dev, nam.nam$b_dev);
   devicedsc.dsc$w_length  = nam.nam$b_dev;
   chan = 0;
@@ -1029,16 +1146,16 @@ __gnat_set_file_time_name (name, time_stamp)
   if ((status & 1) != 1)
     LIB$SIGNAL (status);
 
-  /*  Initialize the FIB and fill in the directory id field. */
-  bzero (&fib, sizeof (fib));
-  fib.fib$w_did [0]  = nam.nam$w_did [0];
-  fib.fib$w_did [1]  = nam.nam$w_did [1];
-  fib.fib$w_did [2]  = nam.nam$w_did [2];
+  /* Initialize the FIB and fill in the directory id field.  */
+  memset (&fib, 0, sizeof (fib));
+  fib.fib$w_did[0]  = nam.nam$w_did[0];
+  fib.fib$w_did[1]  = nam.nam$w_did[1];
+  fib.fib$w_did[2]  = nam.nam$w_did[2];
   fib.fib$l_acctl = 0;
   fib.fib$l_wcc = 0;
   strcpy (file.string, (strrchr (result.string, ']') + 1));
   filedsc.dsc$w_length = strlen (file.string);
-  result.string [result.length = 0] = 0;
+  result.string[result.length = 0] = 0;
 
   /* Open and close the file to fill in the attributes.  */
   status
@@ -1049,29 +1166,27 @@ __gnat_set_file_time_name (name, time_stamp)
   if ((iosb.status & 1) != 1)
     LIB$SIGNAL (iosb.status);
 
-  result.string [result.length] = 0;
-  status = SYS$QIOW (0, chan, IO$_DEACCESS, &iosb, 0, 0,
-                     &fibdsc, 0, 0, 0, &atrlst, 0);
+  result.string[result.length] = 0;
+  status = SYS$QIOW (0, chan, IO$_DEACCESS, &iosb, 0, 0, &fibdsc, 0, 0, 0,
+                    &atrlst, 0);
   if ((status & 1) != 1)
     LIB$SIGNAL (status);
   if ((iosb.status & 1) != 1)
     LIB$SIGNAL (iosb.status);
 
-  /* Set creation time to requested time */
-  unix_time_to_vms (time_stamp, newtime);
-
   {
     time_t t;
-    struct tm *ts;
+
+    /* Set creation time to requested time.  */
+    unix_time_to_vms (time_stamp, newtime);
 
     t = time ((time_t) 0);
-    ts = localtime (&t);
 
-    /* Set revision time to now in local time. */
-    unix_time_to_vms (t + ts->tm_gmtoff, revtime);
+    /* Set revision time to now in local time.  */
+    unix_time_to_vms (t, revtime);
   }
 
-  /*  Reopen the file, modify the times and then close. */
+  /* Reopen the file, modify the times and then close.  */
   fib.fib$l_acctl = FIB$M_WRITE;
   status
     = SYS$QIOW (0, chan, IO$_ACCESS|IO$M_ACCESS, &iosb, 0, 0,
@@ -1091,7 +1206,7 @@ __gnat_set_file_time_name (name, time_stamp)
   if ((iosb.status & 1) != 1)
     LIB$SIGNAL (iosb.status);
 
-  /* Deassign the channel and exit. */
+  /* Deassign the channel and exit.  */
   status = SYS$DASSGN (chan);
   if ((status & 1) != 1)
     LIB$SIGNAL (status);
@@ -1099,10 +1214,10 @@ __gnat_set_file_time_name (name, time_stamp)
   struct utimbuf utimbuf;
   time_t t;
 
-  /* Set modification time to requested time */
+  /* Set modification time to requested time */
   utimbuf.modtime = time_stamp;
 
-  /* Set access time to now in local time */
+  /* Set access time to now in local time */
   t = time ((time_t) 0);
   utimbuf.actime = mktime (localtime (&t));
 
@@ -1111,10 +1226,7 @@ __gnat_set_file_time_name (name, time_stamp)
 }
 
 void
-__gnat_get_env_value_ptr (name, len, value)
-     char *name;
-     int *len;
-     char **value;
+__gnat_get_env_value_ptr (char *name, int *len, char **value)
 {
   *value = getenv (name);
   if (!*value)
@@ -1129,46 +1241,51 @@ __gnat_get_env_value_ptr (name, len, value)
 
 #ifdef VMS
 
-static char *to_host_path_spec PROTO ((char *));
+static char *to_host_path_spec (char *);
 
 struct descriptor_s
 {
   unsigned short len, mbz;
-  char *adr;
+  __char_ptr32 adr;
 };
 
 typedef struct _ile3
 {
   unsigned short len, code;
-  char *adr;
+  __char_ptr32 adr;
   unsigned short *retlen_adr;
 } ile_s;
 
 #endif
 
 void
-__gnat_set_env_value (name, value)
-     char *name;
-     char *value;
+__gnat_set_env_value (char *name, char *value)
 {
 #ifdef MSDOS
 
 #elif defined (VMS)
   struct descriptor_s name_desc;
-  /* Put in JOB table for now, so that the project stuff at least works */
+  /* Put in JOB table for now, so that the project stuff at least works */
   struct descriptor_s table_desc = {7, 0, "LNM$JOB"};
-  char *host_pathspec = to_host_path_spec (value);
+  char *host_pathspec = value;
   char *copy_pathspec;
   int num_dirs_in_pathspec = 1;
   char *ptr;
-
-  if (*host_pathspec == 0)
-    return;
+  long status;
 
   name_desc.len = strlen (name);
   name_desc.mbz = 0;
   name_desc.adr = name;
 
+  if (*host_pathspec == 0)
+    /* deassign */
+    {
+      status = LIB$DELETE_LOGICAL (&name_desc, &table_desc);
+      /* no need to check status; if the logical name is not
+         defined, that's fine. */
+      return;
+    }
+
   ptr = host_pathspec;
   while (*ptr++)
     if (*ptr == ',')
@@ -1189,22 +1306,22 @@ __gnat_set_env_value (name, value)
          next = strchr (curr, 0);
 
        *next = 0;
-       ile_array [i].len = strlen (curr);
+       ile_array[i].len = strlen (curr);
 
-       /* Code 2 from lnmdef.h means its a string */
-       ile_array [i].code = 2;
-       ile_array [i].adr = curr;
+       /* Code 2 from lnmdef.h means its a string */
+       ile_array[i].code = 2;
+       ile_array[i].adr = curr;
 
-       /* retlen_adr is ignored */
-       ile_array [i].retlen_adr = 0;
+       /* retlen_adr is ignored */
+       ile_array[i].retlen_adr = 0;
        curr = next + 1;
       }
 
-    /* Terminating item must be zero */
-    ile_array [i].len = 0;
-    ile_array [i].code = 0;
-    ile_array [i].adr = 0;
-    ile_array [i].retlen_adr = 0;
+    /* Terminating item must be zero */
+    ile_array[i].len = 0;
+    ile_array[i].code = 0;
+    ile_array[i].adr = 0;
+    ile_array[i].retlen_adr = 0;
 
     status = LIB$SET_LOGICAL (&name_desc, 0, &table_desc, 0, ile_array);
     if ((status & 1) != 1)
@@ -1231,7 +1348,7 @@ __gnat_set_env_value (name, value)
    key.  */
 
 char *
-__gnat_get_libraries_from_registry ()
+__gnat_get_libraries_from_registry (void)
 {
   char *result = (char *) "";
 
@@ -1264,7 +1381,7 @@ __gnat_get_libraries_from_registry ()
     {
       value_size = name_size = 256;
       res = RegEnumValue (reg_key, index, name, &name_size, 0,
-                          &type, value, &value_size);
+                          &type, (LPBYTE)value, &value_size);
 
       if (res == ERROR_SUCCESS && type == REG_SZ)
         {
@@ -1286,27 +1403,28 @@ __gnat_get_libraries_from_registry ()
 }
 
 int
-__gnat_stat (name, statbuf)
-     char *name;
-     struct stat *statbuf;
+__gnat_stat (char *name, struct stat *statbuf)
 {
 #ifdef _WIN32
   /* Under Windows the directory name for the stat function must not be
      terminated by a directory separator except if just after a drive name.  */
   int name_len  = strlen (name);
-  char last_char = name [name_len - 1];
-  char win32_name [4096];
+  char last_char = name[name_len - 1];
+  char win32_name[GNAT_MAX_PATH_LEN + 2];
+
+  if (name_len > GNAT_MAX_PATH_LEN)
+    return -1;
 
   strcpy (win32_name, name);
 
   while (name_len > 1 && (last_char == '\\' || last_char == '/'))
     {
-      win32_name [name_len - 1] = '\0';
+      win32_name[name_len - 1] = '\0';
       name_len--;
       last_char = win32_name[name_len - 1];
     }
 
-  if (name_len == 2 && win32_name [1] == ':')
+  if (name_len == 2 && win32_name[1] == ':')
     strcat (win32_name, "\\");
 
   return stat (win32_name, statbuf);
@@ -1317,28 +1435,26 @@ __gnat_stat (name, statbuf)
 }
 
 int
-__gnat_file_exists (name)
-     char *name;
+__gnat_file_exists (char *name)
 {
   struct stat statbuf;
 
   return !__gnat_stat (name, &statbuf);
 }
 
-int    
-__gnat_is_absolute_path (name)
-     char *name;
+int
+__gnat_is_absolute_path (char *name, int length)
 {
-  return (*name == '/' || *name == DIR_SEPARATOR
-#if defined(__EMX__) || defined(MSDOS) || defined(WINNT)
-      || strlen (name) > 1 && isalpha (name [0]) && name [1] == ':'
+  return (length != 0) &&
+     (*name == '/' || *name == DIR_SEPARATOR
+#if defined (__EMX__) || defined (MSDOS) || defined (WINNT)
+      || (length > 1 && isalpha (name[0]) && name[1] == ':')
 #endif
          );
 }
 
 int
-__gnat_is_regular_file (name)
-     char *name;
+__gnat_is_regular_file (char *name)
 {
   int ret;
   struct stat statbuf;
@@ -1348,8 +1464,7 @@ __gnat_is_regular_file (name)
 }
 
 int
-__gnat_is_directory (name)
-     char *name;
+__gnat_is_directory (char *name)
 {
   int ret;
   struct stat statbuf;
@@ -1359,8 +1474,19 @@ __gnat_is_directory (name)
 }
 
 int
-__gnat_is_writable_file (name)
-     char *name;
+__gnat_is_readable_file (char *name)
+{
+  int ret;
+  int mode;
+  struct stat statbuf;
+
+  ret = __gnat_stat (name, &statbuf);
+  mode = statbuf.st_mode & S_IRUSR;
+  return (!ret && mode);
+}
+
+int
+__gnat_is_writable_file (char *name)
 {
   int ret;
   int mode;
@@ -1371,11 +1497,65 @@ __gnat_is_writable_file (name)
   return (!ret && mode);
 }
 
-#ifdef VMS
-/* Defined in VMS header files */
-#define fork() (decc$$alloc_vfork_blocks() >= 0 ? \
-               LIB$GET_CURRENT_INVO_CONTEXT (decc$$get_vfork_jmpbuf()) : -1)
+void
+__gnat_set_writable (char *name)
+{
+#ifndef __vxworks
+  struct stat statbuf;
+
+  if (stat (name, &statbuf) == 0)
+  {
+    statbuf.st_mode = statbuf.st_mode | S_IWUSR;
+    chmod (name, statbuf.st_mode);
+  }
+#endif
+}
+
+void
+__gnat_set_executable (char *name)
+{
+#ifndef __vxworks
+  struct stat statbuf;
+
+  if (stat (name, &statbuf) == 0)
+  {
+    statbuf.st_mode = statbuf.st_mode | S_IXUSR;
+    chmod (name, statbuf.st_mode);
+  }
+#endif
+}
+
+void
+__gnat_set_readonly (char *name)
+{
+#ifndef __vxworks
+  struct stat statbuf;
+
+  if (stat (name, &statbuf) == 0)
+  {
+    statbuf.st_mode = statbuf.st_mode & 07577;
+    chmod (name, statbuf.st_mode);
+  }
+#endif
+}
+
+int
+__gnat_is_symbolic_link (char *name ATTRIBUTE_UNUSED)
+{
+#if defined (__vxworks)
+  return 0;
+
+#elif defined (_AIX) || defined (__APPLE__) || defined (__unix__)
+  int ret;
+  struct stat statbuf;
+
+  ret = lstat (name, &statbuf);
+  return (!ret && S_ISLNK (statbuf.st_mode));
+
+#else
+  return 0;
 #endif
+}
 
 #if defined (sun) && defined (__SVR4)
 /* Using fork on Solaris will duplicate all the threads. fork1, which
@@ -1385,55 +1565,99 @@ __gnat_is_writable_file (name)
 #endif
 
 int
-__gnat_portable_spawn (args)
-    char *args[];
+__gnat_portable_spawn (char *args[])
 {
   int status = 0;
-  int finished;
-  int pid;
+  int finished ATTRIBUTE_UNUSED;
+  int pid ATTRIBUTE_UNUSED;
 
 #if defined (MSDOS) || defined (_WIN32)
-  status = spawnvp (P_WAIT, args [0], args);
+  /* args[0] must be quotes as it could contain a full pathname with spaces */
+  char *args_0 = args[0];
+  args[0] = (char *)xmalloc (strlen (args_0) + 3);
+  strcpy (args[0], "\"");
+  strcat (args[0], args_0);
+  strcat (args[0], "\"");
+
+  status = spawnvp (P_WAIT, args_0, (const char* const*)args);
+
+  /* restore previous value */
+  free (args[0]);
+  args[0] = (char *)args_0;
+
   if (status < 0)
-    return 4;
+    return -1;
   else
     return status;
 
-#elif defined(__vxworks)  /* Mods for VxWorks */
-  pid = sp (args[0], args);  /* Spawn process and save pid */
-  if (pid == -1)
-    return (4);
-
-  while (taskIdVerify(pid) >= 0)
-    /* Wait until spawned task is complete then continue.  */
-    ;
+#elif defined (__vxworks)
+  return -1;
 #else
 
 #ifdef __EMX__
-  pid = spawnvp (P_NOWAIT, args [0], args);
+  pid = spawnvp (P_NOWAIT, args[0], args);
   if (pid == -1)
-    return (4);
+    return -1;
+
 #else
   pid = fork ();
-  if (pid == -1)
-    return (4);
+  if (pid < 0)
+    return -1;
 
-  if (pid == 0 && execv (args [0], args) != 0)
-    _exit (1);
+  if (pid == 0)
+    {
+      /* The child. */
+      if (execv (args[0], MAYBE_TO_PTR32 (args)) != 0)
+#if defined (VMS)
+       return -1; /* execv is in parent context on VMS.  */
+#else
+       _exit (1);
+#endif
+    }
 #endif
 
-  /* The parent */
+  /* The parent */
   finished = waitpid (pid, &status, 0);
 
   if (finished != pid || WIFEXITED (status) == 0)
-    return 4;
+    return -1;
 
   return WEXITSTATUS (status);
 #endif
+
   return 0;
 }
 
-/* WIN32 code to implement a wait call that wait for any child process */
+/* Create a copy of the given file descriptor.
+   Return -1 if an error occurred.  */
+
+int
+__gnat_dup (int oldfd)
+{
+#if defined (__vxworks)
+   /* Not supported on VxWorks.  */
+   return -1;
+#else
+   return dup (oldfd);
+#endif
+}
+
+/* Make newfd be the copy of oldfd, closing newfd first if necessary.
+   Return -1 if an error occurred.  */
+
+int
+__gnat_dup2 (int oldfd, int newfd)
+{
+#if defined (__vxworks)
+  /* Not supported on VxWorks.  */
+  return -1;
+#else
+  return dup2 (oldfd, newfd);
+#endif
+}
+
+/* WIN32 code to implement a wait call that wait for any child process.  */
+
 #ifdef _WIN32
 
 /* Synchronization code, to be thread safe.  */
@@ -1441,19 +1665,19 @@ __gnat_portable_spawn (args)
 static CRITICAL_SECTION plist_cs;
 
 void
-__gnat_plist_init ()
+__gnat_plist_init (void)
 {
   InitializeCriticalSection (&plist_cs);
 }
 
 static void
-plist_enter ()
+plist_enter (void)
 {
   EnterCriticalSection (&plist_cs);
 }
 
-void
-plist_leave ()
+static void
+plist_leave (void)
 {
   LeaveCriticalSection (&plist_cs);
 }
@@ -1469,8 +1693,7 @@ static Process_List *PLIST = NULL;
 static int plist_length = 0;
 
 static void
-add_handle (h)
-     HANDLE h;
+add_handle (HANDLE h)
 {
   Process_List *pl;
 
@@ -1488,10 +1711,11 @@ add_handle (h)
   plist_leave();
 }
 
-void remove_handle (h)
-     HANDLE h;
+static void
+remove_handle (HANDLE h)
 {
-  Process_List *pl, *prev;
+  Process_List *pl;
+  Process_List *prev = NULL;
 
   plist_enter();
 
@@ -1522,18 +1746,26 @@ void remove_handle (h)
 }
 
 static int
-win32_no_block_spawn (command, args)
-     char *command;
-     char *args[];
+win32_no_block_spawn (char *command, char *args[])
 {
   BOOL result;
   STARTUPINFO SI;
   PROCESS_INFORMATION PI;
   SECURITY_ATTRIBUTES SA;
-
-  char full_command [2000];
+  int csize = 1;
+  char *full_command;
   int k;
 
+  /* compute the total command line length */
+  k = 0;
+  while (args[k])
+    {
+      csize += strlen (args[k]) + 1;
+      k++;
+    }
+
+  full_command = (char *) xmalloc (csize);
+
   /* Startup info. */
   SI.cb          = sizeof (STARTUPINFO);
   SI.lpReserved  = NULL;
@@ -1561,8 +1793,11 @@ win32_no_block_spawn (command, args)
       k++;
     }
 
-  result = CreateProcess (NULL, (char *) full_command, &SA, NULL, TRUE,
-                          NORMAL_PRIORITY_CLASS, NULL, NULL, &SI, &PI);
+  result = CreateProcess
+            (NULL, (char *) full_command, &SA, NULL, TRUE,
+              GetPriorityClass (GetCurrentProcess()), NULL, NULL, &SI, &PI);
+
+  free (full_command);
 
   if (result == TRUE)
     {
@@ -1575,8 +1810,7 @@ win32_no_block_spawn (command, args)
 }
 
 static int
-win32_wait (status)
-     int *status;
+win32_wait (int *status)
 {
   DWORD exitcode;
   HANDLE *hl;
@@ -1608,7 +1842,7 @@ win32_wait (status)
   plist_leave();
 
   res = WaitForMultipleObjects (plist_length, hl, FALSE, INFINITE);
-  h = hl [res - WAIT_OBJECT_0];
+  h = hl[res - WAIT_OBJECT_0];
   free (hl);
 
   remove_handle (h);
@@ -1623,8 +1857,7 @@ win32_wait (status)
 #endif
 
 int
-__gnat_portable_no_block_spawn (args)
-    char *args[];
+__gnat_portable_no_block_spawn (char *args[])
 {
   int pid = 0;
 
@@ -1638,7 +1871,7 @@ __gnat_portable_no_block_spawn (args)
      portable_wait below systematically returns a pid of 0 and reports that
      the subprocess terminated successfully. */
 
-  if (spawnvp (P_WAIT, args [0], args) != 0)
+  if (spawnvp (P_WAIT, args[0], args) != 0)
     return -1;
 
 #elif defined (_WIN32)
@@ -1646,26 +1879,30 @@ __gnat_portable_no_block_spawn (args)
   pid = win32_no_block_spawn (args[0], args);
   return pid;
 
-#elif defined (__vxworks) /* Mods for VxWorks */
-  pid = sp (args[0], args);  /* Spawn task and then return (no waiting) */
-  if (pid == -1)
-    return (4);
-
-  return pid;
+#elif defined (__vxworks)
+  return -1;
 
 #else
   pid = fork ();
 
-  if (pid == 0 && execv (args [0], args) != 0)
-    _exit (1);
+  if (pid == 0)
+    {
+      /* The child.  */
+      if (execv (args[0], MAYBE_TO_PTR32 (args)) != 0)
+#if defined (VMS)
+       return -1; /* execv is in parent context on VMS. */
+#else
+       _exit (1);
+#endif
+    }
+
 #endif
 
   return pid;
 }
 
 int
-__gnat_portable_wait (process_status)
-    int *process_status;
+__gnat_portable_wait (int *process_status)
 {
   int status = 0;
   int pid = 0;
@@ -1675,19 +1912,14 @@ __gnat_portable_wait (process_status)
   pid = win32_wait (&status);
 
 #elif defined (__EMX__) || defined (MSDOS)
-  /* ??? See corresponding comment in portable_no_block_spawn. */
+  /* ??? See corresponding comment in portable_no_block_spawn.  */
 
 #elif defined (__vxworks)
   /* Not sure what to do here, so do same as __EMX__ case, i.e., nothing but
-     return zero. */
+     return zero.  */
 #else
 
-#ifdef VMS
-  /* Wait doesn't do the right thing on VMS */
   pid = waitpid (-1, &status, 0);
-#else
-  pid = wait (&status);
-#endif
   status = status & 0xffff;
 #endif
 
@@ -1696,40 +1928,37 @@ __gnat_portable_wait (process_status)
 }
 
 void
-__gnat_os_exit (status)
-     int status;
+__gnat_os_exit (int status)
 {
-#ifdef VMS
-  /* Exit without changing 0 to 1 */
-  __posix_exit (status);
-#else
   exit (status);
-#endif
 }
 
-/* Locate a regular file, give a Path value */
+/* Locate a regular file, give a Path value */
 
 char *
-__gnat_locate_regular_file (file_name, path_val)
-     char *file_name;
-     char *path_val;
+__gnat_locate_regular_file (char *file_name, char *path_val)
 {
   char *ptr;
+  int absolute = __gnat_is_absolute_path (file_name, strlen (file_name));
 
-  /* Handle absolute pathnames. */
+  /* Handle absolute pathnames.  */
+  if (absolute)
+    {
+     if (__gnat_is_regular_file (file_name))
+       return xstrdup (file_name);
+
+      return 0;
+    }
+
+  /* If file_name include directory separator(s), try it first as
+     a path name relative to the current directory */
   for (ptr = file_name; *ptr && *ptr != '/' && *ptr != DIR_SEPARATOR; ptr++)
     ;
 
-  if (*ptr != 0
-#if defined(__EMX__) || defined(MSDOS) || defined(WINNT)
-      || isalpha (file_name [0]) && file_name [1] == ':'
-#endif
-     )
+  if (*ptr != 0)
     {
       if (__gnat_is_regular_file (file_name))
         return xstrdup (file_name);
-
-      return 0;
     }
 
   if (path_val == 0)
@@ -1764,15 +1993,12 @@ __gnat_locate_regular_file (file_name, path_val)
   return 0;
 }
 
-
 /* Locate an executable given a Path argument. This routine is only used by
    gnatbl and should not be used otherwise.  Use locate_exec_on_path
-   instead. */
+   instead.  */
 
 char *
-__gnat_locate_exec (exec_name, path_val)
-     char *exec_name;
-     char *path_val;
+__gnat_locate_exec (char *exec_name, char *path_val)
 {
   if (!strstr (exec_name, HOST_EXECUTABLE_SUFFIX))
     {
@@ -1787,65 +2013,80 @@ __gnat_locate_exec (exec_name, path_val)
     return __gnat_locate_regular_file (exec_name, path_val);
 }
 
-/* Locate an executable using the Systems default PATH */
+/* Locate an executable using the Systems default PATH */
 
 char *
-__gnat_locate_exec_on_path (exec_name)
-     char *exec_name;
+__gnat_locate_exec_on_path (char *exec_name)
 {
+  char *apath_val;
 #ifdef VMS
   char *path_val = "/VAXC$PATH";
 #else
   char *path_val = getenv ("PATH");
 #endif
-  char *apath_val = alloca (strlen (path_val) + 1);
+#ifdef _WIN32
+  /* In Win32 systems we expand the PATH as for XP environment
+     variables are not automatically expanded.  */
+  int len = strlen (path_val) * 3;
+  char *expanded_path_val = alloca (len + 1);
+
+  DWORD res = ExpandEnvironmentStrings (path_val, expanded_path_val, len);
 
+  if (res != 0)
+    {
+      path_val = expanded_path_val;
+    }
+#endif
+
+  apath_val = alloca (strlen (path_val) + 1);
   strcpy (apath_val, path_val);
+
   return __gnat_locate_exec (exec_name, apath_val);
 }
 
 #ifdef VMS
 
 /* These functions are used to translate to and from VMS and Unix syntax
-   file, directory and path specifications. */
+   file, directory and path specifications.  */
 
+#define MAXPATH  256
 #define MAXNAMES 256
 #define NEW_CANONICAL_FILELIST_INCREMENT 64
 
-static char new_canonical_dirspec [255];
-static char new_canonical_filespec [255];
-static char new_canonical_pathspec [MAXNAMES*255];
+static char new_canonical_dirspec [MAXPATH];
+static char new_canonical_filespec [MAXPATH];
+static char new_canonical_pathspec [MAXNAMES*MAXPATH];
 static unsigned new_canonical_filelist_index;
 static unsigned new_canonical_filelist_in_use;
 static unsigned new_canonical_filelist_allocated;
 static char **new_canonical_filelist;
-static char new_host_pathspec [MAXNAMES*255];
-static char new_host_dirspec [255];
-static char new_host_filespec [255];
+static char new_host_pathspec [MAXNAMES*MAXPATH];
+static char new_host_dirspec [MAXPATH];
+static char new_host_filespec [MAXPATH];
 
 /* Routine is called repeatedly by decc$from_vms via
    __gnat_to_canonical_file_list_init until it returns 0 or the expansion
    runs out. */
 
 static int
-wildcard_translate_unix (name)
-     char *name;
+wildcard_translate_unix (char *name)
 {
   char *ver;
-  char buff [256];
+  char buff [MAXPATH];
 
-  strcpy (buff, name);
+  strncpy (buff, name, MAXPATH);
+  buff [MAXPATH - 1] = (char) 0;
   ver = strrchr (buff, '.');
 
-  /* Chop off the version */
+  /* Chop off the version */
   if (ver)
     *ver = 0;
 
-  /* Dynamically extend the allocation by the increment */
+  /* Dynamically extend the allocation by the increment */
   if (new_canonical_filelist_in_use == new_canonical_filelist_allocated)
     {
       new_canonical_filelist_allocated += NEW_CANONICAL_FILELIST_INCREMENT;
-      new_canonical_filelist = (char **) realloc
+      new_canonical_filelist = (char **) xrealloc
        (new_canonical_filelist,
         new_canonical_filelist_allocated * sizeof (char *));
     }
@@ -1855,29 +2096,28 @@ wildcard_translate_unix (name)
   return 1;
 }
 
-/* Translate a wildcard VMS file spec into a list of Unix file
-   specs. First do full translation and copy the results into a list (_init),
-   then return them one at a time (_next). If onlydirs set, only expand
-   directory files. */
+/* Translate a wildcard VMS file spec into a list of Unix file specs. First do
+   full translation and copy the results into a list (_init), then return them
+   one at a time (_next). If onlydirs set, only expand directory files.  */
 
 int
-__gnat_to_canonical_file_list_init (filespec, onlydirs)
-     char *filespec;
-     int onlydirs;
+__gnat_to_canonical_file_list_init (char *filespec, int onlydirs)
 {
   int len;
-  char buff [256];
+  char buff [MAXPATH];
 
   len = strlen (filespec);
-  strcpy (buff, filespec);
+  strncpy (buff, filespec, MAXPATH);
 
   /* Only look for directories */
   if (onlydirs && !strstr (&buff [len-5], "*.dir"))
-    strcat (buff, "*.dir");
+    strncat (buff, "*.dir", MAXPATH);
+
+  buff [MAXPATH - 1] = (char) 0;
 
   decc$from_vms (buff, wildcard_translate_unix, 1);
 
-  /* Remove the .dir extension */
+  /* Remove the .dir extension */
   if (onlydirs)
     {
       int i;
@@ -1885,7 +2125,7 @@ __gnat_to_canonical_file_list_init (filespec, onlydirs)
 
       for (i = 0; i < new_canonical_filelist_in_use; i++)
        {
-         ext = strstr (new_canonical_filelist [i], ".dir");
+         ext = strstr (new_canonical_filelist[i], ".dir");
          if (ext)
            *ext = 0;
        }
@@ -1894,15 +2134,15 @@ __gnat_to_canonical_file_list_init (filespec, onlydirs)
   return new_canonical_filelist_in_use;
 }
 
-/* Return the next filespec in the list */
+/* Return the next filespec in the list */
 
 char *
 __gnat_to_canonical_file_list_next ()
 {
-  return new_canonical_filelist [new_canonical_filelist_index++];
+  return new_canonical_filelist[new_canonical_filelist_index++];
 }
 
-/* Free up storage used in the wildcard expansion */
+/* Free storage used in the wildcard expansion.  */
 
 void
 __gnat_to_canonical_file_list_free ()
@@ -1910,7 +2150,7 @@ __gnat_to_canonical_file_list_free ()
   int i;
 
    for (i = 0; i < new_canonical_filelist_in_use; i++)
-     free (new_canonical_filelist [i]);
+     free (new_canonical_filelist[i]);
 
   free (new_canonical_filelist);
 
@@ -1920,15 +2160,13 @@ __gnat_to_canonical_file_list_free ()
   new_canonical_filelist = 0;
 }
 
-/* Translate a VMS syntax directory specification in to Unix syntax.
-   If prefixflag is set, append an underscore "/". If no indicators
-   of VMS syntax found, return input string. Also translate a dirname
-   that contains no slashes, in case it's a logical name. */
+/* Translate a VMS syntax directory specification in to Unix syntax.  If
+   PREFIXFLAG is set, append an underscore "/". If no indicators of VMS syntax
+   found, return input string. Also translate a dirname that contains no
+   slashes, in case it's a logical name.  */
 
 char *
-__gnat_to_canonical_dir_spec (dirspec,prefixflag)
-     char *dirspec;
-     int prefixflag;
+__gnat_to_canonical_dir_spec (char *dirspec, int prefixflag)
 {
   int len;
 
@@ -1938,54 +2176,84 @@ __gnat_to_canonical_dir_spec (dirspec,prefixflag)
       char *dirspec1;
 
       if (strchr (dirspec, ']') || strchr (dirspec, ':'))
-        strcpy (new_canonical_dirspec, (char *) decc$translate_vms (dirspec));
+       {
+         strncpy (new_canonical_dirspec,
+                  (char *) decc$translate_vms (dirspec),
+                  MAXPATH);
+       }
       else if (!strchr (dirspec, '/') && (dirspec1 = getenv (dirspec)) != 0)
-        strcpy (new_canonical_dirspec, (char *) decc$translate_vms (dirspec1));
+       {
+         strncpy (new_canonical_dirspec,
+                 (char *) decc$translate_vms (dirspec1),
+                 MAXPATH);
+       }
       else
-        strcpy (new_canonical_dirspec, dirspec);
+       {
+         strncpy (new_canonical_dirspec, dirspec, MAXPATH);
+       }
     }
 
   len = strlen (new_canonical_dirspec);
   if (prefixflag && new_canonical_dirspec [len-1] != '/')
-    strcat (new_canonical_dirspec, "/");
+    strncat (new_canonical_dirspec, "/", MAXPATH);
+
+  new_canonical_dirspec [MAXPATH - 1] = (char) 0;
 
   return new_canonical_dirspec;
 
 }
 
 /* Translate a VMS syntax file specification into Unix syntax.
-   If no indicators of VMS syntax found, return input string. */
+   If no indicators of VMS syntax found, check if its an uppercase
+   alphanumeric_ name and if so try it out as an environment
+   variable (logical name). If all else fails return the
+   input string.  */
 
 char *
-__gnat_to_canonical_file_spec (filespec)
-     char *filespec;
+__gnat_to_canonical_file_spec (char *filespec)
 {
-  strcpy (new_canonical_filespec, "");
+  char *filespec1;
+
+  strncpy (new_canonical_filespec, "", MAXPATH);
+
   if (strchr (filespec, ']') || strchr (filespec, ':'))
-    strcpy (new_canonical_filespec, (char *) decc$translate_vms (filespec));
+    {
+      strncpy (new_canonical_filespec,
+              (char *) decc$translate_vms (filespec), MAXPATH);
+    }
+  else if ((strlen (filespec) == strspn (filespec,
+           "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"))
+       && (filespec1 = getenv (filespec)))
+    {
+      strncpy (new_canonical_filespec,
+              (char *) decc$translate_vms (filespec1), MAXPATH);
+    }
   else
-    strcpy (new_canonical_filespec, filespec);
+    {
+      strncpy (new_canonical_filespec, filespec, MAXPATH);
+    }
+
+  new_canonical_filespec [MAXPATH - 1] = (char) 0;
 
   return new_canonical_filespec;
 }
 
 /* Translate a VMS syntax path specification into Unix syntax.
-   If no indicators of VMS syntax found, return input string. */
+   If no indicators of VMS syntax found, return input string.  */
 
 char *
-__gnat_to_canonical_path_spec (pathspec)
-     char *pathspec;
+__gnat_to_canonical_path_spec (char *pathspec)
 {
-  char *curr, *next, buff [256];
+  char *curr, *next, buff [MAXPATH];
 
   if (pathspec == 0)
     return pathspec;
 
-  /* If there are /'s, assume it's a Unix path spec and return */
+  /* If there are /'s, assume it's a Unix path spec and return */
   if (strchr (pathspec, '/'))
     return pathspec;
 
-  new_canonical_pathspec [0] = 0;
+  new_canonical_pathspec[0] = 0;
   curr = pathspec;
 
   for (;;)
@@ -1995,9 +2263,9 @@ __gnat_to_canonical_path_spec (pathspec)
         next = strchr (curr, 0);
 
       strncpy (buff, curr, next - curr);
-      buff [next - curr] = 0;
+      buff[next - curr] = 0;
 
-      /* Check for wildcards and expand if present */
+      /* Check for wildcards and expand if present */
       if (strchr (buff, '*') || strchr (buff, '%') || strstr (buff, "..."))
         {
           int i, dirs;
@@ -2008,57 +2276,57 @@ __gnat_to_canonical_path_spec (pathspec)
               char *next_dir;
 
               next_dir = __gnat_to_canonical_file_list_next ();
-              strcat (new_canonical_pathspec, next_dir);
+              strncat (new_canonical_pathspec, next_dir, MAXPATH);
 
-              /* Don't append the separator after the last expansion */
+              /* Don't append the separator after the last expansion */
               if (i+1 < dirs)
-                strcat (new_canonical_pathspec, ":");
+                strncat (new_canonical_pathspec, ":", MAXPATH);
             }
 
          __gnat_to_canonical_file_list_free ();
         }
       else
-       strcat (new_canonical_pathspec,
-               __gnat_to_canonical_dir_spec (buff, 0));
+       strncat (new_canonical_pathspec,
+               __gnat_to_canonical_dir_spec (buff, 0), MAXPATH);
 
       if (*next == 0)
         break;
 
-      strcat (new_canonical_pathspec, ":");
+      strncat (new_canonical_pathspec, ":", MAXPATH);
       curr = next + 1;
     }
 
+  new_canonical_pathspec [MAXPATH - 1] = (char) 0;
+
   return new_canonical_pathspec;
 }
 
-static char filename_buff [256];
+static char filename_buff [MAXPATH];
 
 static int
-translate_unix (name, type)
-     char *name;
-     int type;
+translate_unix (char *name, int type)
 {
-  strcpy (filename_buff, name);
+  strncpy (filename_buff, name, MAXPATH);
+  filename_buff [MAXPATH - 1] = (char) 0;
   return 0;
 }
 
-/* Translate a Unix syntax path spec into a VMS style (comma separated
-   list of directories. Only used in this file so make it static */
+/* Translate a Unix syntax path spec into a VMS style (comma separated list of
+   directories.  */
 
 static char *
-to_host_path_spec (pathspec)
-     char *pathspec;
+to_host_path_spec (char *pathspec)
 {
-  char *curr, *next, buff [256];
+  char *curr, *next, buff [MAXPATH];
 
   if (pathspec == 0)
     return pathspec;
 
-  /* Can't very well test for colons, since that's the Unix separator! */
+  /* Can't very well test for colons, since that's the Unix separator!  */
   if (strchr (pathspec, ']') || strchr (pathspec, ','))
     return pathspec;
 
-  new_host_pathspec [0] = 0;
+  new_host_pathspec[0] = 0;
   curr = pathspec;
 
   for (;;)
@@ -2068,64 +2336,68 @@ to_host_path_spec (pathspec)
         next = strchr (curr, 0);
 
       strncpy (buff, curr, next - curr);
-      buff [next - curr] = 0;
+      buff[next - curr] = 0;
 
-      strcat (new_host_pathspec, __gnat_to_host_dir_spec (buff, 0));
+      strncat (new_host_pathspec, __gnat_to_host_dir_spec (buff, 0), MAXPATH);
       if (*next == 0)
         break;
-      strcat (new_host_pathspec, ",");
+      strncat (new_host_pathspec, ",", MAXPATH);
       curr = next + 1;
     }
 
+  new_host_pathspec [MAXPATH - 1] = (char) 0;
+
   return new_host_pathspec;
 }
 
-/* Translate a Unix syntax directory specification into VMS syntax.
-   The prefixflag has no effect, but is kept for symmetry with
-   to_canonical_dir_spec.
-   If indicators of VMS syntax found, return input string. */
+/* Translate a Unix syntax directory specification into VMS syntax.  The
+   PREFIXFLAG has no effect, but is kept for symmetry with
+   to_canonical_dir_spec.  If indicators of VMS syntax found, return input
+   string. */
 
 char *
-__gnat_to_host_dir_spec (dirspec, prefixflag)
-     char *dirspec;
-     int prefixflag;
+__gnat_to_host_dir_spec (char *dirspec, int prefixflag ATTRIBUTE_UNUSED)
 {
   int len = strlen (dirspec);
 
-  strcpy (new_host_dirspec, dirspec);
+  strncpy (new_host_dirspec, dirspec, MAXPATH);
+  new_host_dirspec [MAXPATH - 1] = (char) 0;
 
   if (strchr (new_host_dirspec, ']') || strchr (new_host_dirspec, ':'))
     return new_host_dirspec;
 
-  while (len > 1 && new_host_dirspec [len-1] == '/')
+  while (len > 1 && new_host_dirspec[len - 1] == '/')
     {
-      new_host_dirspec [len-1] = 0;
+      new_host_dirspec[len - 1] = 0;
       len--;
     }
 
   decc$to_vms (new_host_dirspec, translate_unix, 1, 2);
-  strcpy (new_host_dirspec, filename_buff);
+  strncpy (new_host_dirspec, filename_buff, MAXPATH);
+  new_host_dirspec [MAXPATH - 1] = (char) 0;
 
   return new_host_dirspec;
-
 }
 
 /* Translate a Unix syntax file specification into VMS syntax.
-   If indicators of VMS syntax found, return input string. */
+   If indicators of VMS syntax found, return input string.  */
 
 char *
-__gnat_to_host_file_spec (filespec)
-     char *filespec;
+__gnat_to_host_file_spec (char *filespec)
 {
-  strcpy (new_host_filespec, "");
+  strncpy (new_host_filespec, "", MAXPATH);
   if (strchr (filespec, ']') || strchr (filespec, ':'))
-    strcpy (new_host_filespec, filespec);
+    {
+      strncpy (new_host_filespec, filespec, MAXPATH);
+    }
   else
     {
       decc$to_vms (filespec, translate_unix, 1, 1);
-      strcpy (new_host_filespec, filename_buff);
+      strncpy (new_host_filespec, filename_buff, MAXPATH);
     }
 
+  new_host_filespec [MAXPATH - 1] = (char) 0;
+
   return new_host_filespec;
 }
 
@@ -2135,83 +2407,76 @@ __gnat_adjust_os_resource_limits ()
   SYS$ADJWSL (131072, 0);
 }
 
-#else
+#else /* VMS */
 
-/* Dummy functions for Osint import for non-VMS systems */
+/* Dummy functions for Osint import for non-VMS systems */
 
 int
-__gnat_to_canonical_file_list_init (dirspec, onlydirs)
-     char *dirspec ATTRIBUTE_UNUSED;
-     int onlydirs ATTRIBUTE_UNUSED;
+__gnat_to_canonical_file_list_init
+  (char *dirspec ATTRIBUTE_UNUSED, int onlydirs ATTRIBUTE_UNUSED)
 {
   return 0;
 }
 
 char *
-__gnat_to_canonical_file_list_next ()
+__gnat_to_canonical_file_list_next (void)
 {
   return (char *) "";
 }
 
 void
-__gnat_to_canonical_file_list_free ()
+__gnat_to_canonical_file_list_free (void)
 {
 }
 
 char *
-__gnat_to_canonical_dir_spec (dirspec, prefixflag)
-     char *dirspec;
-     int prefixflag ATTRIBUTE_UNUSED;
+__gnat_to_canonical_dir_spec (char *dirspec, int prefixflag ATTRIBUTE_UNUSED)
 {
   return dirspec;
 }
 
 char *
-__gnat_to_canonical_file_spec (filespec)
-     char *filespec;
+__gnat_to_canonical_file_spec (char *filespec)
 {
   return filespec;
 }
 
 char *
-__gnat_to_canonical_path_spec (pathspec)
-     char *pathspec;
+__gnat_to_canonical_path_spec (char *pathspec)
 {
   return pathspec;
 }
 
 char *
-__gnat_to_host_dir_spec (dirspec, prefixflag)
-     char *dirspec;
-     int prefixflag ATTRIBUTE_UNUSED;
+__gnat_to_host_dir_spec (char *dirspec, int prefixflag ATTRIBUTE_UNUSED)
 {
   return dirspec;
 }
 
 char *
-__gnat_to_host_file_spec (filespec)
-        char *filespec;
+__gnat_to_host_file_spec (char *filespec)
 {
   return filespec;
 }
 
 void
-__gnat_adjust_os_resource_limits ()
+__gnat_adjust_os_resource_limits (void)
 {
 }
 
 #endif
 
-/* for EMX, we cannot include dummy in libgcc, since it is too difficult
+/* For EMX, we cannot include dummy in libgcc, since it is too difficult
    to coordinate this with the EMX distribution. Consequently, we put the
-   definition of dummy() which is used for exception handling, here */
+   definition of dummy which is used for exception handling, here.  */
 
 #if defined (__EMX__)
 void __dummy () {}
 #endif
 
 #if defined (__mips_vxworks)
-int _flush_cache()
+int
+_flush_cache()
 {
    CACHE_USER_FLUSH (0, ENTIRE_CACHE);
 }
@@ -2219,22 +2484,151 @@ int _flush_cache()
 
 #if defined (CROSS_COMPILE)  \
   || (! (defined (sparc) && defined (sun) && defined (__SVR4)) \
-      && ! defined (linux) \
-      && ! defined (sgi) \
-      && ! defined (hpux) \
+      && ! (defined (linux) && defined (i386)) \
+      && ! defined (__FreeBSD__) \
+      && ! defined (__hpux__) \
+      && ! defined (__APPLE__) \
+      && ! defined (_AIX) \
       && ! (defined (__alpha__)  && defined (__osf__)) \
-      && ! defined (__MINGW32__))
-/* Dummy function to satisfy g-trasym.o.
-   Currently Solaris sparc, HP/UX, IRIX, GNU/Linux, Tru64 & Windows provide a
-   non-dummy version of this procedure in libaddr2line.a */
+      && ! defined (__MINGW32__) \
+      && ! (defined (__mips) && defined (__sgi)))
+
+/* Dummy function to satisfy g-trasym.o.  Currently Solaris sparc, HP/UX,
+   GNU/Linux x86, Tru64 & Windows provide a non-dummy version of this
+   procedure in libaddr2line.a.  */
 
 void
-convert_addresses (addrs, n_addr, buf, len)
-     void *addrs ATTRIBUTE_UNUSED;
-     int n_addr ATTRIBUTE_UNUSED;
-     void *buf ATTRIBUTE_UNUSED;
-     int *len;
+convert_addresses (void *addrs ATTRIBUTE_UNUSED,
+                  int n_addr ATTRIBUTE_UNUSED,
+                  void *buf ATTRIBUTE_UNUSED,
+                  int *len ATTRIBUTE_UNUSED)
 {
   *len = 0;
 }
 #endif
+
+#if defined (_WIN32)
+int __gnat_argument_needs_quote = 1;
+#else
+int __gnat_argument_needs_quote = 0;
+#endif
+
+/* This option is used to enable/disable object files handling from the
+   binder file by the GNAT Project module. For example, this is disabled on
+   Windows (prior to GCC 3.4) as it is already done by the mdll module.
+   Stating with GCC 3.4 the shared libraries are not based on mdll
+   anymore as it uses the GCC's -shared option  */
+#if defined (_WIN32) \
+    && ((__GNUC__ < 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ < 4)))
+int __gnat_prj_add_obj_files = 0;
+#else
+int __gnat_prj_add_obj_files = 1;
+#endif
+
+/* char used as prefix/suffix for environment variables */
+#if defined (_WIN32)
+char __gnat_environment_char = '%';
+#else
+char __gnat_environment_char = '$';
+#endif
+
+/* This functions copy the file attributes from a source file to a
+   destination file.
+
+   mode = 0  : In this mode copy only the file time stamps (last access and
+               last modification time stamps).
+
+   mode = 1  : In this mode, time stamps and read/write/execute attributes are
+               copied.
+
+   Returns 0 if operation was successful and -1 in case of error. */
+
+int
+__gnat_copy_attribs (char *from, char *to, int mode)
+{
+#if defined (VMS) || defined (__vxworks)
+  return -1;
+#else
+  struct stat fbuf;
+  struct utimbuf tbuf;
+
+  if (stat (from, &fbuf) == -1)
+    {
+      return -1;
+    }
+
+  tbuf.actime = fbuf.st_atime;
+  tbuf.modtime = fbuf.st_mtime;
+
+  if (utime (to, &tbuf) == -1)
+    {
+      return -1;
+    }
+
+  if (mode == 1)
+    {
+      if (chmod (to, fbuf.st_mode) == -1)
+       {
+         return -1;
+       }
+    }
+
+  return 0;
+#endif
+}
+
+/* This function is installed in libgcc.a.  */
+extern void __gnat_install_locks (void (*) (void), void (*) (void));
+
+/* This function offers a hook for libgnarl to set the
+   locking subprograms for libgcc_eh.
+   This is only needed on OpenVMS, since other platforms use standard
+   --enable-threads=posix option, or similar.  */
+
+void
+__gnatlib_install_locks (void (*lock) (void) ATTRIBUTE_UNUSED,
+                         void (*unlock) (void) ATTRIBUTE_UNUSED)
+{
+#if defined (IN_RTS) && defined (VMS)
+  __gnat_install_locks (lock, unlock);
+  /* There is a bootstrap path issue if adaint is build with this
+     symbol unresolved for the stage1 compiler. Since the compiler
+     does not use tasking, we simply make __gnatlib_install_locks
+     a no-op in this case. */
+#endif
+}
+
+int
+__gnat_lseek (int fd, long offset, int whence)
+{
+  return (int) lseek (fd, offset, whence);
+}
+
+/* This function returns the version of GCC being used.  Here it's GCC 3.  */
+int
+get_gcc_version (void)
+{
+  return 3;
+}
+
+int
+__gnat_set_close_on_exec (int fd ATTRIBUTE_UNUSED,
+                        int close_on_exec_p ATTRIBUTE_UNUSED)
+{
+#if defined (F_GETFD) && defined (FD_CLOEXEC) && ! defined (__vxworks)
+  int flags = fcntl (fd, F_GETFD, 0);
+  if (flags < 0)
+    return flags;
+  if (close_on_exec_p)
+    flags |= FD_CLOEXEC;
+  else
+    flags &= ~FD_CLOEXEC;
+  return fcntl (fd, F_SETFD, flags | FD_CLOEXEC);
+#else
+  return -1;
+  /* For the Windows case, we should use SetHandleInformation to remove
+     the HANDLE_INHERIT property from fd. This is not implemented yet,
+     but for our purposes (support of GNAT.Expect) this does not matter,
+     as by default handles are *not* inherited. */
+#endif
+}