gcc-8.3/gcc/execute()
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
*参照元 [#k36921b1]
#backlinks
*説明 [#z23f58d0]
-パス: [[gcc-8.3/gcc/gcc.c]]
-FIXME: これは何?
--説明
**引数 [#k628c198]
-なし
**返り値 [#na102ad6]
-int
--
**参考 [#e7886444]
*実装 [#i0faf42f]
/* Execute the command specified by the arguments on the...
When using pipes, this includes several piped-togethe...
with `|' between them.
Return 0 if successful, -1 if failed. */
static int
execute (void)
{
int i;
int n_commands; /* # of command. */
char *string;
struct pex_obj *pex;
struct command
{
const char *prog; /* program name. */
const char **argv; /* vector of args. */
};
const char *arg;
struct command *commands; /* each command buffer with ...
gcc_assert (!processing_spec_function);
if (wrapper_string)
{
string = find_a_file (&exec_prefixes,
argbuf[0], X_OK, false);
if (string)
argbuf[0] = string;
insert_wrapper (wrapper_string);
}
/* Count # of piped commands. */
for (n_commands = 1, i = 0; argbuf.iterate (i, &arg); ...
if (strcmp (arg, "|") == 0)
n_commands++;
/* Get storage for each command. */
commands = (struct command *) alloca (n_commands * siz...
/* Split argbuf into its separate piped processes,
and record info about each one.
Also search for the programs that are to be run. */
argbuf.safe_push (0);
commands[0].prog = argbuf[0]; /* first command. */
commands[0].argv = argbuf.address ();
if (!wrapper_string)
{
string = find_a_file (&exec_prefixes, commands[0]....
commands[0].argv[0] = (string) ? string : commands...
}
for (n_commands = 1, i = 0; argbuf.iterate (i, &arg); ...
if (arg && strcmp (arg, "|") == 0)
{ /* each command. */
#if defined (__MSDOS__) || defined (OS2) || defined (VMS)
fatal_error (input_location, "-pipe not supported");
#endif
argbuf[i] = 0; /* Termination of
command args. */
commands[n_commands].prog = argbuf[i + 1];
commands[n_commands].argv
= &(argbuf.address ())[i + 1];
string = find_a_file (&exec_prefixes, commands[n_comman...
X_OK, false);
if (string)
commands[n_commands].argv[0] = string;
n_commands++;
}
/* If -v, print what we are about to do, and maybe que...
if (verbose_flag)
{
/* For help listings, put a blank line between sub...
if (print_help_list)
fputc ('\n', stderr);
/* Print each piped command as a separate line. */
for (i = 0; i < n_commands; i++)
{
const char *const *j;
if (verbose_only_flag)
{
for (j = commands[i].argv; *j; j++)
{
const char *p;
for (p = *j; *p; ++p)
if (!ISALNUM ((unsigned char) *p)
&& *p != '_' && *p != '/' && *p != '-' && *p != '.')
break;
if (*p || !*j)
{
fprintf (stderr, " \"");
for (p = *j; *p; ++p)
{
if (*p == '"' || *p == '\\' || *p == '$')
fputc ('\\', stderr);
fputc (*p, stderr);
}
fputc ('"', stderr);
}
/* If it's empty, print "". */
else if (!**j)
fprintf (stderr, " \"\"");
else
fprintf (stderr, " %s", *j);
}
}
else
for (j = commands[i].argv; *j; j++)
/* If it's empty, print "". */
if (!**j)
fprintf (stderr, " \"\"");
else
fprintf (stderr, " %s", *j);
/* Print a pipe symbol after all but the last command...
if (i + 1 != n_commands)
fprintf (stderr, " |");
fprintf (stderr, "\n");
}
fflush (stderr);
if (verbose_only_flag != 0)
{
/* verbose_only_flag should act as if the spec was
executed, so increment execution_count before
returning. This prevents spurious warnings about
unused linker input files, etc. */
execution_count++;
return 0;
}
#ifdef DEBUG
fnotice (stderr, "\nGo ahead? (y or n) ");
fflush (stderr);
i = getchar ();
if (i != '\n')
while (getchar () != '\n')
;
if (i != 'y' && i != 'Y')
return 0;
#endif /* DEBUG */
}
#ifdef ENABLE_VALGRIND_CHECKING
/* Run the each command through valgrind. To simplify...
path to valgrind and the option "-q" (for quiet ope...
something triggers), we allocate a separate argv ar...
for (i = 0; i < n_commands; i++)
{
const char **argv;
int argc;
int j;
for (argc = 0; commands[i].argv[argc] != NULL; arg...
;
argv = XALLOCAVEC (const char *, argc + 3);
argv[0] = VALGRIND_PATH;
argv[1] = "-q";
for (j = 2; j < argc + 2; j++)
argv[j] = commands[i].argv[j - 2];
argv[j] = NULL;
commands[i].argv = argv;
commands[i].prog = argv[0];
}
#endif
/* Run each piped subprocess. */
pex = pex_init (PEX_USE_PIPES | ((report_times || repo...
? PEX_RECORD_TIMES : 0),
progname, temp_filename);
if (pex == NULL)
fatal_error (input_location, "pex_init failed: %m");
for (i = 0; i < n_commands; i++)
{
const char *errmsg;
int err;
const char *string = commands[i].argv[0];
errmsg = pex_run (pex,
((i + 1 == n_commands ? PEX_LAST : 0)
| (string == commands[i].prog ? PEX_SEARCH : 0)),
string, CONST_CAST (char **, commands[i].argv),
NULL, NULL, &err);
-
--サブコマンド(cc1, as, ld など)の起動を行う
--[[gcc-8.3/gcc/pex_run()]]
if (errmsg != NULL)
{
if (err == 0)
fatal_error (input_location, errmsg);
else
{
errno = err;
pfatal_with_name (errmsg);
}
}
if (i && string != commands[i].prog)
free (CONST_CAST (char *, string));
}
execution_count++;
/* Wait for all the subprocesses to finish. */
{
int *statuses;
struct pex_time *times = NULL;
int ret_code = 0;
statuses = (int *) alloca (n_commands * sizeof (int));
if (!pex_get_status (pex, n_commands, statuses))
fatal_error (input_location, "failed to get exit s...
if (report_times || report_times_to_file)
{
times = (struct pex_time *) alloca (n_commands * sizeof...
if (!pex_get_times (pex, n_commands, times))
fatal_error (input_location, "failed to get process t...
}
pex_free (pex);
for (i = 0; i < n_commands; ++i)
{
int status = statuses[i];
if (WIFSIGNALED (status))
switch (WTERMSIG (status))
{
case SIGINT:
case SIGTERM:
/* SIGQUIT and SIGKILL are not available on MinGW...
#ifdef SIGQUIT
case SIGQUIT:
#endif
#ifdef SIGKILL
case SIGKILL:
#endif
/* The user (or environment) did something to the
inferior. Making this an ICE confuses the user into
thinking there's a compiler bug. Much more likely is
the user or OOM killer nuked it. */
fatal_error (input_location,
"%s signal terminated program %s",
strsignal (WTERMSIG (status)),
commands[i].prog);
break;
#ifdef SIGPIPE
case SIGPIPE:
/* SIGPIPE is a special case. It happens in -pip...
when the compiler dies before the preprocessor is
done, or the assembler dies before the compiler is
done. There's generally been an error already, and
this is just fallout. So don't generate another
error unless we would otherwise have succeeded. */
if (signal_count || greatest_status >= MIN_FATAL_...
{
signal_count++;
ret_code = -1;
break;
}
#endif
/* FALLTHROUGH */
default:
/* The inferior failed to catch the signal. */
internal_error_no_backtrace ("%s signal terminate...
strsignal (WTERMSIG (status)),
commands[i].prog);
}
else if (WIFEXITED (status)
&& WEXITSTATUS (status) >= MIN_FATAL_STATUS)
{
/* For ICEs in cc1, cc1obj, cc1plus see if it is
reproducible or not. */
const char *p;
if (flag_report_bug
&& WEXITSTATUS (status) == ICE_EXIT_CODE
&& i == 0
&& (p = strrchr (commands[0].argv[0], DIR_SEPARATOR))
&& ! strncmp (p + 1, "cc1", 3))
try_generate_repro (commands[0].argv);
if (WEXITSTATUS (status) > greatest_status)
greatest_status = WEXITSTATUS (status);
ret_code = -1;
}
if (report_times || report_times_to_file)
{
struct pex_time *pt = ×[i];
double ut, st;
ut = ((double) pt->user_seconds
+ (double) pt->user_microseconds / 1.0e6);
st = ((double) pt->system_seconds
+ (double) pt->system_microseconds / 1.0e6);
if (ut + st != 0)
{
if (report_times)
fnotice (stderr, "# %s %.2f %.2f\n",
commands[i].prog, ut, st);
if (report_times_to_file)
{
int c = 0;
const char *const *j;
fprintf (report_times_to_file, "%g %g", ut, st);
for (j = &commands[i].prog; *j; j = &commands[i].a...
{
const char *p;
for (p = *j; *p; ++p)
if (*p == '"' || *p == '\\' || *p == '$'
|| ISSPACE (*p))
break;
if (*p)
{
fprintf (report_times_to_file, " \"");
for (p = *j; *p; ++p)
{
if (*p == '"' || *p == '\\' || *p == '$')
fputc ('\\', report_times_to_file);
fputc (*p, report_times_to_file);
}
fputc ('"', report_times_to_file);
}
else
fprintf (report_times_to_file, " %s", *j);
}
fputc ('\n', report_times_to_file);
}
}
}
}
if (commands[0].argv[0] != commands[0].prog)
free (CONST_CAST (char *, commands[0].argv[0]));
return ret_code;
}
}
*コメント [#d35e01e9]
終了行:
*参照元 [#k36921b1]
#backlinks
*説明 [#z23f58d0]
-パス: [[gcc-8.3/gcc/gcc.c]]
-FIXME: これは何?
--説明
**引数 [#k628c198]
-なし
**返り値 [#na102ad6]
-int
--
**参考 [#e7886444]
*実装 [#i0faf42f]
/* Execute the command specified by the arguments on the...
When using pipes, this includes several piped-togethe...
with `|' between them.
Return 0 if successful, -1 if failed. */
static int
execute (void)
{
int i;
int n_commands; /* # of command. */
char *string;
struct pex_obj *pex;
struct command
{
const char *prog; /* program name. */
const char **argv; /* vector of args. */
};
const char *arg;
struct command *commands; /* each command buffer with ...
gcc_assert (!processing_spec_function);
if (wrapper_string)
{
string = find_a_file (&exec_prefixes,
argbuf[0], X_OK, false);
if (string)
argbuf[0] = string;
insert_wrapper (wrapper_string);
}
/* Count # of piped commands. */
for (n_commands = 1, i = 0; argbuf.iterate (i, &arg); ...
if (strcmp (arg, "|") == 0)
n_commands++;
/* Get storage for each command. */
commands = (struct command *) alloca (n_commands * siz...
/* Split argbuf into its separate piped processes,
and record info about each one.
Also search for the programs that are to be run. */
argbuf.safe_push (0);
commands[0].prog = argbuf[0]; /* first command. */
commands[0].argv = argbuf.address ();
if (!wrapper_string)
{
string = find_a_file (&exec_prefixes, commands[0]....
commands[0].argv[0] = (string) ? string : commands...
}
for (n_commands = 1, i = 0; argbuf.iterate (i, &arg); ...
if (arg && strcmp (arg, "|") == 0)
{ /* each command. */
#if defined (__MSDOS__) || defined (OS2) || defined (VMS)
fatal_error (input_location, "-pipe not supported");
#endif
argbuf[i] = 0; /* Termination of
command args. */
commands[n_commands].prog = argbuf[i + 1];
commands[n_commands].argv
= &(argbuf.address ())[i + 1];
string = find_a_file (&exec_prefixes, commands[n_comman...
X_OK, false);
if (string)
commands[n_commands].argv[0] = string;
n_commands++;
}
/* If -v, print what we are about to do, and maybe que...
if (verbose_flag)
{
/* For help listings, put a blank line between sub...
if (print_help_list)
fputc ('\n', stderr);
/* Print each piped command as a separate line. */
for (i = 0; i < n_commands; i++)
{
const char *const *j;
if (verbose_only_flag)
{
for (j = commands[i].argv; *j; j++)
{
const char *p;
for (p = *j; *p; ++p)
if (!ISALNUM ((unsigned char) *p)
&& *p != '_' && *p != '/' && *p != '-' && *p != '.')
break;
if (*p || !*j)
{
fprintf (stderr, " \"");
for (p = *j; *p; ++p)
{
if (*p == '"' || *p == '\\' || *p == '$')
fputc ('\\', stderr);
fputc (*p, stderr);
}
fputc ('"', stderr);
}
/* If it's empty, print "". */
else if (!**j)
fprintf (stderr, " \"\"");
else
fprintf (stderr, " %s", *j);
}
}
else
for (j = commands[i].argv; *j; j++)
/* If it's empty, print "". */
if (!**j)
fprintf (stderr, " \"\"");
else
fprintf (stderr, " %s", *j);
/* Print a pipe symbol after all but the last command...
if (i + 1 != n_commands)
fprintf (stderr, " |");
fprintf (stderr, "\n");
}
fflush (stderr);
if (verbose_only_flag != 0)
{
/* verbose_only_flag should act as if the spec was
executed, so increment execution_count before
returning. This prevents spurious warnings about
unused linker input files, etc. */
execution_count++;
return 0;
}
#ifdef DEBUG
fnotice (stderr, "\nGo ahead? (y or n) ");
fflush (stderr);
i = getchar ();
if (i != '\n')
while (getchar () != '\n')
;
if (i != 'y' && i != 'Y')
return 0;
#endif /* DEBUG */
}
#ifdef ENABLE_VALGRIND_CHECKING
/* Run the each command through valgrind. To simplify...
path to valgrind and the option "-q" (for quiet ope...
something triggers), we allocate a separate argv ar...
for (i = 0; i < n_commands; i++)
{
const char **argv;
int argc;
int j;
for (argc = 0; commands[i].argv[argc] != NULL; arg...
;
argv = XALLOCAVEC (const char *, argc + 3);
argv[0] = VALGRIND_PATH;
argv[1] = "-q";
for (j = 2; j < argc + 2; j++)
argv[j] = commands[i].argv[j - 2];
argv[j] = NULL;
commands[i].argv = argv;
commands[i].prog = argv[0];
}
#endif
/* Run each piped subprocess. */
pex = pex_init (PEX_USE_PIPES | ((report_times || repo...
? PEX_RECORD_TIMES : 0),
progname, temp_filename);
if (pex == NULL)
fatal_error (input_location, "pex_init failed: %m");
for (i = 0; i < n_commands; i++)
{
const char *errmsg;
int err;
const char *string = commands[i].argv[0];
errmsg = pex_run (pex,
((i + 1 == n_commands ? PEX_LAST : 0)
| (string == commands[i].prog ? PEX_SEARCH : 0)),
string, CONST_CAST (char **, commands[i].argv),
NULL, NULL, &err);
-
--サブコマンド(cc1, as, ld など)の起動を行う
--[[gcc-8.3/gcc/pex_run()]]
if (errmsg != NULL)
{
if (err == 0)
fatal_error (input_location, errmsg);
else
{
errno = err;
pfatal_with_name (errmsg);
}
}
if (i && string != commands[i].prog)
free (CONST_CAST (char *, string));
}
execution_count++;
/* Wait for all the subprocesses to finish. */
{
int *statuses;
struct pex_time *times = NULL;
int ret_code = 0;
statuses = (int *) alloca (n_commands * sizeof (int));
if (!pex_get_status (pex, n_commands, statuses))
fatal_error (input_location, "failed to get exit s...
if (report_times || report_times_to_file)
{
times = (struct pex_time *) alloca (n_commands * sizeof...
if (!pex_get_times (pex, n_commands, times))
fatal_error (input_location, "failed to get process t...
}
pex_free (pex);
for (i = 0; i < n_commands; ++i)
{
int status = statuses[i];
if (WIFSIGNALED (status))
switch (WTERMSIG (status))
{
case SIGINT:
case SIGTERM:
/* SIGQUIT and SIGKILL are not available on MinGW...
#ifdef SIGQUIT
case SIGQUIT:
#endif
#ifdef SIGKILL
case SIGKILL:
#endif
/* The user (or environment) did something to the
inferior. Making this an ICE confuses the user into
thinking there's a compiler bug. Much more likely is
the user or OOM killer nuked it. */
fatal_error (input_location,
"%s signal terminated program %s",
strsignal (WTERMSIG (status)),
commands[i].prog);
break;
#ifdef SIGPIPE
case SIGPIPE:
/* SIGPIPE is a special case. It happens in -pip...
when the compiler dies before the preprocessor is
done, or the assembler dies before the compiler is
done. There's generally been an error already, and
this is just fallout. So don't generate another
error unless we would otherwise have succeeded. */
if (signal_count || greatest_status >= MIN_FATAL_...
{
signal_count++;
ret_code = -1;
break;
}
#endif
/* FALLTHROUGH */
default:
/* The inferior failed to catch the signal. */
internal_error_no_backtrace ("%s signal terminate...
strsignal (WTERMSIG (status)),
commands[i].prog);
}
else if (WIFEXITED (status)
&& WEXITSTATUS (status) >= MIN_FATAL_STATUS)
{
/* For ICEs in cc1, cc1obj, cc1plus see if it is
reproducible or not. */
const char *p;
if (flag_report_bug
&& WEXITSTATUS (status) == ICE_EXIT_CODE
&& i == 0
&& (p = strrchr (commands[0].argv[0], DIR_SEPARATOR))
&& ! strncmp (p + 1, "cc1", 3))
try_generate_repro (commands[0].argv);
if (WEXITSTATUS (status) > greatest_status)
greatest_status = WEXITSTATUS (status);
ret_code = -1;
}
if (report_times || report_times_to_file)
{
struct pex_time *pt = ×[i];
double ut, st;
ut = ((double) pt->user_seconds
+ (double) pt->user_microseconds / 1.0e6);
st = ((double) pt->system_seconds
+ (double) pt->system_microseconds / 1.0e6);
if (ut + st != 0)
{
if (report_times)
fnotice (stderr, "# %s %.2f %.2f\n",
commands[i].prog, ut, st);
if (report_times_to_file)
{
int c = 0;
const char *const *j;
fprintf (report_times_to_file, "%g %g", ut, st);
for (j = &commands[i].prog; *j; j = &commands[i].a...
{
const char *p;
for (p = *j; *p; ++p)
if (*p == '"' || *p == '\\' || *p == '$'
|| ISSPACE (*p))
break;
if (*p)
{
fprintf (report_times_to_file, " \"");
for (p = *j; *p; ++p)
{
if (*p == '"' || *p == '\\' || *p == '$')
fputc ('\\', report_times_to_file);
fputc (*p, report_times_to_file);
}
fputc ('"', report_times_to_file);
}
else
fprintf (report_times_to_file, " %s", *j);
}
fputc ('\n', report_times_to_file);
}
}
}
}
if (commands[0].argv[0] != commands[0].prog)
free (CONST_CAST (char *, commands[0].argv[0]));
return ret_code;
}
}
*コメント [#d35e01e9]
ページ名: