OSDN Git Service

2010-08-27 Jerry DeLisle <jvdelisle@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / lto-wrapper.c
index 536ca09..da120b3 100644 (file)
@@ -40,11 +40,19 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "tm.h"
+#include <errno.h>
+#include <signal.h>
+#if ! defined( SIGCHLD ) && defined( SIGCLD )
+#  define SIGCHLD SIGCLD
+#endif
 #include "intl.h"
 #include "libiberty.h"
 #include "obstack.h"
 
+#ifndef HAVE_KILL
+#define kill(p,s) raise(s)
+#endif
+
 int debug;                             /* true if -save-temps.  */
 int verbose;                           /* true if -v.  */
 
@@ -67,36 +75,45 @@ static char *makefile;
 
 static void maybe_unlink_file (const char *);
 
-/* Delete tempfiles and exit function.  */
+ /* Delete tempfiles.  */
 
 static void
-lto_wrapper_exit (int status)
+lto_wrapper_cleanup (void)
 {
   static bool cleanup_done = false;
-  if (!cleanup_done)
+  unsigned int i;
+
+  if (cleanup_done)
+    return;
+
+  /* Setting cleanup_done prevents an infinite loop if one of the
+     calls to maybe_unlink_file fails. */
+  cleanup_done = true;
+
+  if (ltrans_output_file)
+    maybe_unlink_file (ltrans_output_file);
+  if (flto_out)
+    maybe_unlink_file (flto_out);
+  if (args_name)
+    maybe_unlink_file (args_name);
+  if (makefile)
+    maybe_unlink_file (makefile);
+  for (i = 0; i < nr; ++i)
     {
-      unsigned int i;
-
-      /* Setting cleanup_done prevents an infinite loop if one of the
-         calls to maybe_unlink_file fails. */
-      cleanup_done = true;
-
-      if (ltrans_output_file)
-        maybe_unlink_file (ltrans_output_file);
-      if (flto_out)
-        maybe_unlink_file (flto_out);
-      if (args_name)
-        maybe_unlink_file (args_name);
-      if (makefile)
-       maybe_unlink_file (makefile);
-      for (i = 0; i < nr; ++i)
-       {
-         maybe_unlink_file (input_names[i]);
-         if (output_names[i])
-           maybe_unlink_file (output_names[i]);
-       }
+      maybe_unlink_file (input_names[i]);
+      if (output_names[i])
+       maybe_unlink_file (output_names[i]);
     }
-  exit (status);
+}
+
+static void
+fatal_signal (int signum)
+{
+  signal (signum, SIG_DFL);
+  lto_wrapper_cleanup ();
+  /* Get the same signal again, this time not handled,
+     so its normal effect occurs.  */
+  kill (getpid (), signum);
 }
 
 /* Just die. CMSGID is the error message. */
@@ -112,7 +129,8 @@ fatal (const char * cmsgid, ...)
   fprintf (stderr, "\n");
   va_end (ap);
 
-  lto_wrapper_exit (FATAL_EXIT_CODE);
+  lto_wrapper_cleanup ();
+  exit (FATAL_EXIT_CODE);
 }
 
 
@@ -130,7 +148,8 @@ fatal_perror (const char *cmsgid, ...)
   fprintf (stderr, ": %s\n", xstrerror (e));
   va_end (ap);
 
-  lto_wrapper_exit (FATAL_EXIT_CODE);
+  lto_wrapper_cleanup ();
+  exit (FATAL_EXIT_CODE);
 }
 
 
@@ -222,7 +241,8 @@ maybe_unlink_file (const char *file)
 {
   if (! debug)
     {
-      if (unlink_if_ordinary (file))
+      if (unlink_if_ordinary (file)
+         && errno != ENOENT)
        fatal_perror ("deleting LTRANS file %s", file);
     }
   else
@@ -262,6 +282,7 @@ fork_execute (char **argv)
   collect_wait (new_argv[0], pex);
 
   maybe_unlink_file (args_name);
+  args_name = NULL;
   free (at_args);
 }
 
@@ -404,13 +425,21 @@ run_gcc (unsigned argc, char *argv[])
       if (linker_output)
        {
          char *dumpbase = (char *) xmalloc (strlen (linker_output)
-                                            + sizeof(".wpa") + 1);
+                                            + sizeof (".wpa") + 1);
          strcpy (dumpbase, linker_output);
          strcat (dumpbase, ".wpa");
          argv_ptr[0] = dumpbase;
        }
 
-      ltrans_output_file = make_temp_file (".ltrans.out");
+      if (linker_output && debug)
+       {
+         ltrans_output_file = (char *) xmalloc (strlen (linker_output)
+                                                + sizeof (".ltrans.out") + 1);
+         strcpy (ltrans_output_file, linker_output);
+         strcat (ltrans_output_file, ".ltrans.out");
+       }
+      else
+       ltrans_output_file = make_temp_file (".ltrans.out");
       list_option_full = (char *) xmalloc (sizeof (char) *
                         (strlen (ltrans_output_file) + list_option_len + 1));
       tmp = list_option_full;
@@ -513,7 +542,7 @@ cont:
                                      + sizeof(DUMPBASE_SUFFIX) + 1);
              snprintf (dumpbase,
                        strlen (linker_output) + sizeof(DUMPBASE_SUFFIX),
-                       "%s.ltrans%u", linker_output, nr);
+                       "%s.ltrans%u", linker_output, i);
              argv_ptr[0] = dumpbase;
            }
 
@@ -586,6 +615,24 @@ main (int argc, char *argv[])
 {
   gcc_init_libintl ();
 
+  if (signal (SIGINT, SIG_IGN) != SIG_IGN)
+    signal (SIGINT, fatal_signal);
+#ifdef SIGHUP
+  if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
+    signal (SIGHUP, fatal_signal);
+#endif
+  if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
+    signal (SIGTERM, fatal_signal);
+#ifdef SIGPIPE
+  if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
+    signal (SIGPIPE, fatal_signal);
+#endif
+#ifdef SIGCHLD
+  /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
+     receive the signal.  A different setting is inheritable */
+  signal (SIGCHLD, SIG_DFL);
+#endif
+
   /* We may be called with all the arguments stored in some file and
      passed with @file.  Expand them into argv before processing.  */
   expandargv (&argc, &argv);