OSDN Git Service

* make.adb (Gnatmake): Invoke gnatlink with -shared-libgcc when
[pf3gnuchains/gcc-fork.git] / gcc / ada / adaint.c
index 52e0096..8ed3b40 100644 (file)
@@ -6,7 +6,7 @@
  *                                                                          *
  *                          C Implementation File                           *
  *                                                                          *
- *          Copyright (C) 1992-2003, Free Software Foundation, Inc.         *
+ *          Copyright (C) 1992-2004, 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- *
@@ -147,6 +147,8 @@ struct vstring
 #if defined (_WIN32)
 #include <dir.h>
 #include <windows.h>
+#undef DIR_SEPARATOR
+#define DIR_SEPARATOR '\\'
 #endif
 
 #include "adaint.h"
@@ -409,7 +411,8 @@ __gnat_try_lock (char *dir, char *file)
   int fd;
 
   sprintf (full_path, "%s%c%s", dir, DIR_SEPARATOR, file);
-  sprintf (temp_file, "%s-%ld-%ld", dir, (long) getpid(), (long) getppid ());
+  sprintf (temp_file, "%s%cTMP-%ld-%ld",
+           dir, DIR_SEPARATOR, (long)getpid(), (long)getppid ());
 
   /* Create the temporary file and write the process number.  */
   fd = open (temp_file, O_CREAT | O_WRONLY, 0600);
@@ -616,6 +619,21 @@ __gnat_open_create (char *path, int fmode)
 }
 
 int
+__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;
@@ -667,7 +685,7 @@ __gnat_open_new_temp (char *path, int fmode)
 
   strcpy (path, "GNAT-XXXXXX");
 
-#if defined (linux) && !defined (__vxworks)
+#if (defined (__FreeBSD__) || defined (linux)) && !defined (__vxworks)
   return mkstemp (path);
 #elif defined (__Lynx__)
   mktemp (path);
@@ -705,6 +723,21 @@ __gnat_file_length (int fd)
   return (statbuf.st_size);
 }
 
+/* Return the number of bytes in the specified named file.  */
+
+long
+__gnat_named_file_length (char *name)
+{
+  int ret;
+  struct stat statbuf;
+
+  ret = __gnat_stat (name, &statbuf);
+  if (ret || !S_ISREG (statbuf.st_mode))
+    return 0;
+
+  return (statbuf.st_size);
+}
+
 /* Create a temporary filename and put it in string pointed to by
    TMP_FILENAME.  */
 
@@ -742,7 +775,7 @@ __gnat_tmp_name (char *tmp_filename)
     free (pname);
   }
 
-#elif defined (linux)
+#elif defined (linux) || defined (__FreeBSD__)
 #define MAX_SAFE_PATH 1000
   char *tmpdir = getenv ("TMPDIR");
 
@@ -773,7 +806,7 @@ __gnat_readdir (DIR *dirp, char *buffer)
     return NULL;
 
 #else
-  struct dirent *dirent = readdir (dirp);
+  struct dirent *dirent = (struct dirent *) readdir (dirp);
 
   if (dirent != NULL)
     {
@@ -829,7 +862,7 @@ win32_filetime (HANDLE h)
 
 /* Return a GNAT time stamp given a file name.  */
 
-time_t
+OS_Time
 __gnat_file_time_name (char *name)
 {
 
@@ -837,7 +870,7 @@ __gnat_file_time_name (char *name)
   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;
@@ -849,22 +882,25 @@ __gnat_file_time_name (char *name)
       ret = win32_filetime (h);
       CloseHandle (h);
     }
-  return ret;
+  return (OS_Time) ret;
 #else
   struct stat statbuf;
-  (void) __gnat_stat (name, &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
+OS_Time
 __gnat_file_time_fd (int fd)
 {
   /* The following workaround code is due to the fact that under EMX and
@@ -932,24 +968,26 @@ __gnat_file_time_fd (int fd)
   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);
-  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
 }
 
@@ -1310,7 +1348,7 @@ __gnat_get_libraries_from_registry (void)
     {
       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)
         {
@@ -1372,11 +1410,12 @@ __gnat_file_exists (char *name)
 }
 
 int
-__gnat_is_absolute_path (char *name)
+__gnat_is_absolute_path (char *name, int length)
 {
-  return (*name == '/' || *name == DIR_SEPARATOR
+  return (length != 0) &&
+     (*name == '/' || *name == DIR_SEPARATOR
 #if defined (__EMX__) || defined (MSDOS) || defined (WINNT)
-      || (strlen (name) > 1 && isalpha (name[0]) && name[1] == ':')
+      || (length > 1 && isalpha (name[0]) && name[1] == ':')
 #endif
          );
 }
@@ -1440,6 +1479,20 @@ __gnat_set_writable (char *name)
 }
 
 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
@@ -1459,7 +1512,7 @@ __gnat_is_symbolic_link (char *name ATTRIBUTE_UNUSED)
 #if defined (__vxworks)
   return 0;
 
-#elif defined (_AIX) || defined (unix)
+#elif defined (_AIX) || defined (__APPLE__) || defined (__unix__)
   int ret;
   struct stat statbuf;
 
@@ -1497,7 +1550,19 @@ __gnat_portable_spawn (char *args[])
   int pid ATTRIBUTE_UNUSED;
 
 #if defined (MSDOS) || defined (_WIN32)
-  status = spawnvp (P_WAIT, args[0],(const char* const*)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, (char* const*)args);
+
+  /* restore previous value */
+  free (args[0]);
+  args[0] = (char *)args_0;
+
   if (status < 0)
     return -1;
   else
@@ -1541,6 +1606,34 @@ __gnat_portable_spawn (char *args[])
   return 0;
 }
 
+/* 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 occured.  */
+
+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
@@ -1678,8 +1771,9 @@ win32_no_block_spawn (char *command, char *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);
 
@@ -1840,7 +1934,7 @@ char *
 __gnat_locate_regular_file (char *file_name, char *path_val)
 {
   char *ptr;
-  int absolute = __gnat_is_absolute_path (file_name);
+  int absolute = __gnat_is_absolute_path (file_name, strlen (file_name));
 
   /* Handle absolute pathnames.  */
   if (absolute)
@@ -2375,10 +2469,12 @@ _flush_cache()
 #if defined (CROSS_COMPILE)  \
   || (! (defined (sparc) && defined (sun) && defined (__SVR4)) \
       && ! (defined (linux) && defined (i386)) \
-      && ! defined (hpux) \
+      && ! defined (__FreeBSD__) \
+      && ! defined (__hpux__) \
       && ! defined (_AIX) \
       && ! (defined (__alpha__)  && defined (__osf__)) \
-      && ! defined (__MINGW32__))
+      && ! 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
@@ -2402,8 +2498,11 @@ int __gnat_argument_needs_quote = 0;
 
 /* 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 as it is already done by the mdll module. */
-#if defined (_WIN32)
+   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;
@@ -2465,13 +2564,15 @@ __gnat_copy_attribs (char *from, char *to, int mode)
 extern void __gnat_install_locks (void (*) (void), void (*) (void));
 
 /* This function offers a hook for libgnarl to set the
-   locking subprograms for libgcc_eh. */
+   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)
 {
-#ifdef IN_RTS
+#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
@@ -2479,3 +2580,16 @@ __gnatlib_install_locks (void (*lock) (void) ATTRIBUTE_UNUSED,
      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;
+}