/* Utility functions used by tools like collect2 and lto-wrapper.
   Copyright (C) 2009-2021 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT 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
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "intl.h"
#include "diagnostic.h"
#include "obstack.h"
#include "opts.h"
#include "options.h"
#include "simple-object.h"
#include "lto-section-names.h"
#include "collect-utils.h"

static char *response_file;

bool debug;
bool verbose;
bool save_temps;
const char *dumppfx;


/* Notify user of a non-error.  */
void
notice (const char *cmsgid, ...)
{
  va_list ap;

  va_start (ap, cmsgid);
  vfprintf (stderr, _(cmsgid), ap);
  va_end (ap);
}

void
fatal_signal (int signum)
{
  signal (signum, SIG_DFL);
  utils_cleanup (true);
  /* Get the same signal again, this time not handled,
     so its normal effect occurs.  */
  kill (getpid (), signum);
}

/* Setup the signal handlers for the utils. */
void
setup_signals (void)
{
#ifdef SIGQUIT
  if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
    signal (SIGQUIT, fatal_signal);
#endif
  if (signal (SIGINT, SIG_IGN) != SIG_IGN)
    signal (SIGINT, fatal_signal);
#ifdef SIGALRM
  if (signal (SIGALRM, SIG_IGN) != SIG_IGN)
    signal (SIGALRM, fatal_signal);
#endif
#ifdef SIGHUP
  if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
    signal (SIGHUP, fatal_signal);
#endif
  if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
    signal (SIGSEGV, fatal_signal);
  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 SIGBUS
  if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
    signal (SIGBUS, 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
}

/* Wait for a process to finish, and exit if a nonzero status is found.  */

int
collect_wait (const char *prog, struct pex_obj *pex)
{
  int status;

  if (!pex_get_status (pex, 1, &status))
    fatal_error (input_location, "cannot get program status: %m");
  pex_free (pex);

  if (response_file && !save_temps)
    {
      unlink (response_file);
      response_file = NULL;
    }

  if (status)
    {
      if (WIFSIGNALED (status))
	{
	  int sig = WTERMSIG (status);
	  fatal_error (input_location, "%s terminated with signal %d [%s]%s",
		       prog, sig, strsignal (sig),
		       WCOREDUMP (status) ? ", core dumped" : "");
	}

      if (WIFEXITED (status))
	return WEXITSTATUS (status);
    }
  return 0;
}

void
do_wait (const char *prog, struct pex_obj *pex)
{
  int ret = collect_wait (prog, pex);
  if (ret != 0)
    fatal_error (input_location, "%s returned %d exit status", prog, ret);
}


/* Execute a program, and wait for the reply.  */

struct pex_obj *
collect_execute (const char *prog, char **argv, const char *outname,
		 const char *errname, int flags, bool use_atfile,
		 const char *atsuffix)
{
  struct pex_obj *pex;
  const char *errmsg;
  int err;
  char *response_arg = NULL;
  char *response_argv[3];

  if (use_atfile && argv[0] != NULL)
    {
      /* If using @file arguments, create a temporary file and put the
         contents of argv into it.  Then change argv to an array corresponding
         to a single argument @FILE, where FILE is the temporary filename.  */

      char **current_argv = argv + 1;
      char *argv0 = argv[0];
      int status;
      FILE *f;

      /* Note: we assume argv contains at least one element; this is
         checked above.  */

      if (!save_temps || !atsuffix || !dumppfx)
	response_file = make_temp_file ("");
      else
	response_file = concat (dumppfx, atsuffix, NULL);

      f = fopen (response_file, "w");

      if (f == NULL)
        fatal_error (input_location, "could not open response file %s",
		     response_file);

      status = writeargv (current_argv, f);

      if (status)
        fatal_error (input_location, "could not write to response file %s",
		     response_file);

      status = fclose (f);

      if (EOF == status)
        fatal_error (input_location, "could not close response file %s",
		     response_file);

      response_arg = concat ("@", response_file, NULL);
      response_argv[0] = argv0;
      response_argv[1] = response_arg;
      response_argv[2] = NULL;

      argv = response_argv;
    }

  if (verbose || debug)
    {
      char **p_argv;
      const char *str;

      if (argv[0])
	fprintf (stderr, "%s", argv[0]);
      else
	notice ("[cannot find %s]", prog);

      for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++)
	fprintf (stderr, " %s", str);

      fprintf (stderr, "\n");
    }

  fflush (stdout);
  fflush (stderr);

  /* If we cannot find a program we need, complain error.  Do this here
     since we might not end up needing something that we could not find.  */

  if (argv[0] == 0)
    fatal_error (input_location, "cannot find %qs", prog);

  pex = pex_init (0, "collect2", NULL);
  if (pex == NULL)
    fatal_error (input_location, "%<pex_init%> failed: %m");

  errmsg = pex_run (pex, flags, argv[0], argv, outname,
		    errname, &err);
  if (errmsg != NULL)
    {
      if (err != 0)
	{
	  errno = err;
	  fatal_error (input_location, "%s: %m", _(errmsg));
	}
      else
	fatal_error (input_location, errmsg);
    }

  free (response_arg);

  return pex;
}

void
fork_execute (const char *prog, char **argv, bool use_atfile,
	      const char *atsuffix)
{
  struct pex_obj *pex;

  pex = collect_execute (prog, argv, NULL, NULL,
			 PEX_LAST | PEX_SEARCH, use_atfile, atsuffix);
  do_wait (prog, pex);
}

/* Delete tempfiles.  */

void
utils_cleanup (bool from_signal)
{
  static bool cleanup_done = false;

  if (cleanup_done)
    return;

  /* Setting cleanup_done prevents an infinite loop if one of the
     calls to maybe_unlink fails. */
  cleanup_done = true;

  tool_cleanup (from_signal);
}
