diff options
author | bernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-06-26 09:16:28 +0000 |
---|---|---|
committer | bernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-06-26 09:16:28 +0000 |
commit | 39ef03bb3a7080964e11703941c2bdee83f4f433 (patch) | |
tree | ca9b56a1959b3c1e842cc178449311307ce1841f /gcc/collect-utils.c | |
parent | 572cae003b64c085a501636f9ffab6cfb7c31b62 (diff) | |
download | gcc-39ef03bb3a7080964e11703941c2bdee83f4f433.tar.gz |
Part 2 of the collect-utils library, now also used for collect2.
* Makefile.in (COLLECT2_OBJS): Add collect-utils.o.
(LTO_WRAPPER_OBJS): New variable.
(lto-wrapper$(exeext)): Use it.
* collect2.c: Include "collect-utils.h".
(verbose, debug): Remove variables.
(at_file_supplied): No longer static.
(tool_name): New variable.
(do_wait, fork_execute, maybe_unlink): Don't declare.
(tool_cleanup): No longer static.
(notice): Remove function.
(maybe_run_lto_and_relink, main, do_dsymutil): Add new arg to
fork_execute calls.
(collect_wait, do_wait, collect_execute): Remove functions.
(maybe_unlink): No longer static.
* collect2.h (verbose, debug): Don't declare.
(at_file_supplied): Declare.
* collect-utils.c (utils_cleanup): New arg from_signal. All callers
changed.
(collect_execute): Replace with implementation from collect2, plus a
new arg use_atfile. All callers changed.
(collect_wait): Replace with implementation from collect2.
(maybe_unlink_file): Remove function.
(fork_execute): Replace with implementation from collect2, plus a
new arg use_atfile. All callers changed.
(do_wait): Add call to utils_cleanup to the error path.
* collect-utils.h (collect_execute, fork_execute, utils_cleanup,
tool_cleanup): Adjust declarations.
* lto-wrapper.c (tool_cleanup): Add unused bool argument.
* tlink.c: Include "collect-utils.h".
(tlink_execute): New arg use_atfile. All callers changed.
(tlink_init, tlink_execute): Remove declarations.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@212020 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/collect-utils.c')
-rw-r--r-- | gcc/collect-utils.c | 227 |
1 files changed, 117 insertions, 110 deletions
diff --git a/gcc/collect-utils.c b/gcc/collect-utils.c index e92513c18a3..febc5192d14 100644 --- a/gcc/collect-utils.c +++ b/gcc/collect-utils.c @@ -35,24 +35,6 @@ bool debug; bool verbose; bool save_temps; -/* Delete tempfiles. */ - -void -utils_cleanup (void) -{ - 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; - - if (response_file) - maybe_unlink (response_file); - tool_cleanup (); -} /* Notify user of a non-error. */ void @@ -69,62 +51,13 @@ void fatal_signal (int signum) { signal (signum, SIG_DFL); - utils_cleanup (); + utils_cleanup (true); /* Get the same signal again, this time not handled, so its normal effect occurs. */ kill (getpid (), signum); } - -/* Execute a program, and wait for the reply. ARGV are the arguments. The - last one must be NULL. */ - -struct pex_obj * -collect_execute (char **argv) -{ - struct pex_obj *pex; - const char *errmsg; - int err; - - if (verbose) - { - char **p_argv; - const char *str; - - for (p_argv = argv; (str = *p_argv) != (char *) 0; p_argv++) - fprintf (stderr, " %s", str); - - fprintf (stderr, "\n"); - } - - fflush (stdout); - fflush (stderr); - - pex = pex_init (0, tool_name, NULL); - if (pex == NULL) - fatal_error ("pex_init failed: %m"); - - /* Do not use PEX_LAST here, we use our stdout for communicating with - collect2 or the linker-plugin. Any output from the sub-process - will confuse that. */ - errmsg = pex_run (pex, PEX_SEARCH, argv[0], argv, NULL, - NULL, &err); - if (errmsg != NULL) - { - if (err != 0) - { - errno = err; - fatal_error ("%s: %m", _(errmsg)); - } - else - fatal_error (errmsg); - } - - return pex; -} - - -/* Wait for a process to finish, and exit if a nonzero status is found. - PROG is the program name. PEX is the process we should wait for. */ + +/* Wait for a process to finish, and exit if a nonzero status is found. */ int collect_wait (const char *prog, struct pex_obj *pex) @@ -140,18 +73,14 @@ collect_wait (const char *prog, struct pex_obj *pex) if (WIFSIGNALED (status)) { int sig = WTERMSIG (status); - if (WCOREDUMP (status)) - fatal_error ("%s terminated with signal %d [%s], core dumped", - prog, sig, strsignal (sig)); - else - fatal_error ("%s terminated with signal %d [%s]", - prog, sig, strsignal (sig)); + fatal_error ("%s terminated with signal %d [%s]%s", + prog, sig, strsignal (sig), + WCOREDUMP (status) ? ", core dumped" : ""); } if (WIFEXITED (status)) - fatal_error ("%s returned %d exit status", prog, WEXITSTATUS (status)); + return WEXITSTATUS (status); } - return 0; } @@ -169,52 +98,130 @@ do_wait (const char *prog, struct pex_obj *pex) } } -/* Unlink a temporary LTRANS file unless requested otherwise. */ + +/* Execute a program, and wait for the reply. */ -void -maybe_unlink_file (const char *file) +struct pex_obj * +collect_execute (const char *prog, char **argv, const char *outname, + const char *errname, int flags, bool use_atfile) { - if (!debug) + struct pex_obj *pex; + const char *errmsg; + int err; + char *response_arg = NULL; + char *response_argv[3]; + + if (use_atfile && argv[0] != NULL) { - if (unlink_if_ordinary (file) - && errno != ENOENT) - fatal_error ("deleting file %s: %m", file); + /* 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. */ + + response_file = make_temp_file (""); + + f = fopen (response_file, "w"); + + if (f == NULL) + fatal_error ("could not open response file %s", response_file); + + status = writeargv (current_argv, f); + + if (status) + fatal_error ("could not write to response file %s", response_file); + + status = fclose (f); + + if (EOF == status) + fatal_error ("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; } - else - fprintf (stderr, "[Leaving %s]\n", file); -} + 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 ("cannot find '%s'", prog); + + pex = pex_init (0, "collect2", NULL); + if (pex == NULL) + fatal_error ("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 ("%s: %m", _(errmsg)); + } + else + fatal_error (errmsg); + } -/* Execute program ARGV[0] with arguments ARGV. Wait for it to finish. */ + free (response_arg); + + return pex; +} void -fork_execute (char **argv) +fork_execute (const char *prog, char **argv, bool use_atfile) { struct pex_obj *pex; - char *new_argv[3]; - char *at_args; - FILE *args; - int status; - - response_file = make_temp_file (".args"); - at_args = concat ("@", response_file, NULL); - args = fopen (response_file, "w"); - if (args == NULL) - fatal_error ("failed to open %s", response_file); - status = writeargv (&argv[1], args); + pex = collect_execute (prog, argv, NULL, NULL, + PEX_LAST | PEX_SEARCH, use_atfile); + do_wait (prog, pex); +} - if (status) - fatal_error ("could not write to temporary file %s", response_file); +/* Delete tempfiles. */ - fclose (args); +void +utils_cleanup (bool from_signal) +{ + static bool cleanup_done = false; - new_argv[0] = argv[0]; - new_argv[1] = at_args; - new_argv[2] = NULL; + if (cleanup_done) + return; - pex = collect_execute (new_argv); - do_wait (new_argv[0], pex); + /* Setting cleanup_done prevents an infinite loop if one of the + calls to maybe_unlink fails. */ + cleanup_done = true; - free (at_args); + if (response_file) + maybe_unlink (response_file); + tool_cleanup (from_signal); } |