struct pex_obj * collect_execute (const char *prog, char **argv, const char *outname, const char *errname, int flags, bool use_atfile) { 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. */ response_file = make_temp_file (""); 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 '%s'", 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; }
static void exec_lto_wrapper (char *argv[]) { int t, i; int status; char *at_args; FILE *args; FILE *wrapper_output; char *new_argv[3]; struct pex_obj *pex; const char *errmsg; /* Write argv to a file to avoid a command line that is too long. */ arguments_file_name = make_temp_file (""); check (arguments_file_name, LDPL_FATAL, "Failed to generate a temorary file name"); args = fopen (arguments_file_name, "w"); check (args, LDPL_FATAL, "could not open arguments file"); t = writeargv (&argv[1], args); check (t == 0, LDPL_FATAL, "could not write arguments"); t = fclose (args); check (t == 0, LDPL_FATAL, "could not close arguments file"); at_args = concat ("@", arguments_file_name, NULL); check (at_args, LDPL_FATAL, "could not allocate"); for (i = 1; argv[i]; i++) { char *a = argv[i]; if (a[0] == '-' && a[1] == 'v' && a[2] == '\0') { for (i = 0; argv[i]; i++) fprintf (stderr, "%s ", argv[i]); fprintf (stderr, "\n"); break; } } new_argv[0] = argv[0]; new_argv[1] = at_args; new_argv[2] = NULL; if (debug) { for (i = 0; new_argv[i]; i++) fprintf (stderr, "%s ", new_argv[i]); fprintf (stderr, "\n"); } pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL); check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper"); errmsg = pex_run (pex, 0, new_argv[0], new_argv, NULL, NULL, &t); check (errmsg == NULL, LDPL_FATAL, "could not run lto-wrapper"); check (t == 0, LDPL_FATAL, "could not run lto-wrapper"); wrapper_output = pex_read_output (pex, 0); check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output"); add_output_files (wrapper_output); t = pex_get_status (pex, 1, &status); check (t == 1, LDPL_FATAL, "could not get lto-wrapper exit status"); check (WIFEXITED (status) && WEXITSTATUS (status) == 0, LDPL_FATAL, "lto-wrapper failed"); pex_free (pex); free (at_args); }