int collect_wait (const char *prog, struct pex_obj *pex) { int status; if (!pex_get_status (pex, 1, &status)) fatal_error (input_location, "can't 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; }
int execute (const char *name, const char **argv, const char *input, const char *output, const char **errmsg, int *waitstatus) { int errnum; if(input != NULL || output != NULL) { *errmsg = "execute input/output NYI"; return -1; } struct pex_obj *pex = pex_init(0, name, NULL); if (pex == NULL) { *errmsg = "pex_init failed"; return -1; } *errmsg = pex_run(pex, PEX_LAST, name, (char * const *)argv, output, NULL, &errnum); if (*errmsg != NULL || !pex_get_status(pex, 1, waitstatus)) { if (&errmsg == NULL) { *errmsg = "can't get program status"; } pex_free(pex); return -1; } pex_free(pex); return 0; }
int pwait (int pid, int *status, int flags ATTRIBUTE_UNUSED) { /* The PID returned by pexecute is one-based. */ --pid; if (pex == NULL || pid < 0 || pid >= idx) return -1; if (pid == 0 && idx == 1) { if (!pex_get_status (pex, 1, status)) return -1; } else { int *vector; vector = XNEWVEC (int, idx); if (!pex_get_status (pex, idx, vector)) { free (vector); return -1; } *status = vector[pid]; free (vector); } /* Assume that we are done after the caller has retrieved the last exit status. The original implementation did not require that the exit statuses be retrieved in order, but this implementation does. */ if (pid + 1 == idx) { pex_free (pex); pex = NULL; idx = 0; } return pid + 1; }
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); }