00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include <stdio.h>
00045 #include <stdlib.h>
00046 #include <strings.h>
00047 #include <string.h>
00048
00049 #if !defined(_WIN32)
00050 #include <sys/wait.h>
00051 #include <sys/times.h>
00052 #if !defined(__APPLE__)
00053 #include <sys/procfs.h>
00054 #endif
00055 #include <unistd.h>
00056
00057 #else
00058 #include <windows.h>
00059 #include <process.h>
00060 #include <time.h>
00061 #endif
00062 #include <sys/types.h>
00063 #include <sys/stat.h>
00064 #include <fcntl.h>
00065 #include <unistd.h>
00066 #include <errno.h>
00067 #include <signal.h>
00068 #include <malloc.h>
00069 #include <sys/param.h>
00070 #include <limits.h>
00071 #include <alloca.h>
00072 #include <cmplrs/rcodes.h>
00073 #include "run.h"
00074 #include "string_utils.h"
00075 #include "errors.h"
00076 #include "file_names.h"
00077 #include "phases.h"
00078 #include "opt_actions.h"
00079 #include "file_utils.h"
00080 #include "pathscale_defs.h"
00081 #include "option_names.h"
00082 #include "lib_phase_dir.h"
00083
00084 boolean show_flag = FALSE;
00085 boolean show_but_not_run = FALSE;
00086 boolean execute_flag = TRUE;
00087 boolean time_flag = FALSE;
00088 boolean prelink_flag = TRUE;
00089 boolean quiet_flag = TRUE;
00090 boolean run_m4 = FALSE;
00091 static boolean ran_twice = FALSE;
00092 static int f90_fe_status = RC_OKAY;
00093 static char *f90_fe_name = NULL;
00094
00095 static void init_time (void);
00096 static void print_time (char *phase);
00097 static void my_psema(void);
00098 static void my_vsema(void);
00099
00100 #define LOGFILE "/var/log/messages"
00101
00102 #if !defined(__MINGW32__)
00103 static void my_execv(const char *name, char *const argv[])
00104 {
00105 int len = strlen(name);
00106 int passthru = len > 4 && name[len - 4] == '/' &&
00107 (strcmp(name + len - 3, "gcc") == 0 ||
00108 strcmp(name + len - 3, "g++") == 0);
00109
00110 if (show_but_not_run) {
00111 int i;
00112
00113 fprintf(stderr, "\"%s\" ", name);
00114 for (i = 1; argv[i] != NULL; i++)
00115 fprintf(stderr, "\"%s\" ", argv[i]);
00116 fputc('\n', stderr);
00117 if (!passthru)
00118 do_exit (0);
00119 }
00120
00121 execv(name, argv);
00122 error("cannot exec %s: %m", name);
00123 cleanup ();
00124 do_exit (RC_SYSTEM_ERROR);
00125
00126 }
00127 #endif
00128
00129
00130
00131 void
00132 run_simple_program (char *name, char **argv, char *output)
00133 {
00134 #if defined(__MINGW32__)
00135 internal_error("run_simple_program not supported");
00136 #else
00137 int forkpid;
00138 int fdout;
00139 int waitpid;
00140 int waitstatus;
00141 int termsig;
00142
00143
00144 forkpid = fork();
00145 if (forkpid == -1) {
00146 error("no more processes");
00147 cleanup ();
00148 do_exit (RC_SYSTEM_ERROR);
00149
00150 }
00151
00152 if (forkpid == 0) {
00153
00154 if ((fdout = creat (output, 0666)) == -1) {
00155 error ("cannot create output file %s", output);
00156 cleanup ();
00157 do_exit (RC_SYSTEM_ERROR);
00158
00159 }
00160 dup2 (fdout, fileno(stdout));
00161
00162 my_execv(name, argv);
00163 } else {
00164
00165 int procid;
00166 while ((waitpid = wait (&waitstatus)) != forkpid) {
00167 if (waitpid == -1) {
00168 error("bad return from wait");
00169 cleanup();
00170 do_exit(RC_SYSTEM_ERROR);
00171
00172 }
00173 }
00174 if (WIFSTOPPED(waitstatus)) {
00175 termsig = WSTOPSIG(waitstatus);
00176 error("STOPPED signal received from %s", name);
00177 cleanup();
00178 do_exit(RC_SYSTEM_ERROR);
00179
00180 } else if (WIFEXITED(waitstatus)) {
00181 int status = WEXITSTATUS(waitstatus);
00182 if (status != RC_OKAY) {
00183
00184
00185 internal_error("%s returned non-zero status %d",
00186 name, status);
00187 }
00188 return;
00189 } else if(WIFSIGNALED(waitstatus)){
00190 termsig = WTERMSIG(waitstatus);
00191 switch (termsig) {
00192 case SIGHUP:
00193 case SIGINT:
00194 case SIGQUIT:
00195 case SIGKILL:
00196 case SIGTERM:
00197 error("%s died due to signal %d", name, termsig);
00198 break;
00199 default:
00200 internal_error("%s died due to signal %d",
00201 name, termsig);
00202 break;
00203 }
00204 if(WCOREDUMP(waitstatus)) {
00205 error("core dumped");
00206 }
00207 if (termsig == SIGKILL) {
00208 error("Probably caused by running out of swap space -- check %s", LOGFILE);
00209 }
00210 cleanup();
00211 do_exit(RC_SYSTEM_ERROR);
00212 } else {
00213
00214 internal_error("driver exec'ing is confused");
00215 return;
00216 }
00217 }
00218 #endif
00219 }
00220
00221 static void my_putenv(const char *name, const char *fmt, ...)
00222 __attribute__((format (printf, 2, 3)));
00223
00224 static void my_putenv(const char *name, const char *fmt, ...)
00225 {
00226 va_list ap;
00227 char *rhs, *env;
00228 int len;
00229 va_start(ap, fmt);
00230
00231 if (vasprintf(&rhs, fmt, ap) == -1) {
00232 internal_error("cannot allocate memory");
00233 do_exit(RC_SYSTEM_ERROR);
00234 }
00235
00236 if (show_but_not_run)
00237 fprintf(stderr, "%s=\"%s\" ", name, rhs);
00238
00239
00240
00241
00242 if (asprintf(&env, "%s=%s", name, rhs) == -1) {
00243 internal_error("cannot allocate memory");
00244 do_exit(RC_SYSTEM_ERROR);
00245 }
00246
00247 putenv(env);
00248
00249 va_end(ap);
00250 }
00251
00252 char *
00253 get_binutils_lib_path(void)
00254 {
00255 #ifdef PSC_TO_OPEN64
00256 static const char *binutils_library_path = "../i686-pc-linux-gnu/" OPEN64_TARGET "/lib";
00257 #endif
00258 char *my_path;
00259
00260 asprintf(&my_path, "%s/%s", get_executable_dir(),
00261 binutils_library_path);
00262 return my_path;
00263 }
00264
00265
00266 void
00267 run_phase (phases_t phase, char *name, string_list_t *args)
00268 {
00269 char **argv;
00270 int argc;
00271 string_item_t *p;
00272 char *output = NULL;
00273 char *input = NULL;
00274 boolean save_stderr = FALSE;
00275 int fdin, fdout;
00276 int forkpid;
00277 int waitpid;
00278 int waitstatus;
00279 int termsig;
00280 int num_maps;
00281 char *rld_path;
00282 struct stat stat_buf;
00283 const boolean uses_message_system =
00284 (phase == P_f90_fe || phase == P_f90_cpp ||
00285 phase == P_cppf90_fe);
00286
00287 if (show_flag) {
00288
00289 fprintf(stderr, "%s ", name);
00290 print_string_list(stderr, args);
00291 }
00292 if (!execute_flag) return;
00293
00294 if (time_flag) init_time();
00295
00296
00297 argc = 1;
00298 for (p = args->head; p != NULL; p=p->next) {
00299
00300 if (p->name == NULL)
00301 continue;
00302 argc++;
00303 }
00304 argv = (char **) malloc((argc+1)*sizeof(char*));
00305 argv[0] = name;
00306 for (argc = 1, p = args->head; p != NULL; argc++, p=p->next) {
00307
00308 if (p->name[0] == '\0') {
00309 argc--;
00310 continue;
00311 }
00312
00313 if (strcmp(p->name, "<") == 0) {
00314
00315 input = p->next->name;
00316 break;
00317 } else if (strcmp(p->name, ">") == 0) {
00318
00319 output = p->next->name;
00320 break;
00321 } else if (strcmp(p->name, ">&") == 0) {
00322
00323 output = p->next->name;
00324 save_stderr = TRUE;
00325 break;
00326 }
00327 argv[argc] = p->name;
00328 }
00329 argv[argc] = NULL;
00330
00331 #if !defined(__MINGW32__)
00332
00333 forkpid = fork();
00334 if (forkpid == -1) {
00335 error("no more processes");
00336 cleanup ();
00337 do_exit (RC_SYSTEM_ERROR);
00338
00339 }
00340
00341 if (forkpid == 0) {
00342 char *my_path, *l_path, *l32_path, *nls_path, *env_path;
00343
00344
00345
00346
00347 if (input != NULL) {
00348 if ((fdin = open (input, O_RDONLY)) == -1) {
00349 error ("cannot open input file %s", input);
00350 cleanup ();
00351 do_exit (RC_SYSTEM_ERROR);
00352
00353 }
00354 dup2 (fdin, fileno(stdin));
00355 }
00356 if (output != NULL) {
00357 if ((fdout = creat (output, 0666)) == -1) {
00358 error ("cannot create output file %s", output);
00359 cleanup ();
00360 do_exit (RC_SYSTEM_ERROR);
00361
00362 }
00363 if (save_stderr) {
00364 dup2 (fdout, fileno(stderr));
00365 } else {
00366 dup2 (fdout, fileno(stdout));
00367 }
00368 }
00369
00370 my_path = get_binutils_lib_path();
00371 rld_path = get_phase_ld_library_path (phase);
00372
00373 if (rld_path != 0)
00374 asprintf(&my_path, "%s:%s", my_path, rld_path);
00375
00376 l_path = l32_path = my_path;
00377
00378 if (ld_library_path)
00379 asprintf(&l_path, "%s:%s", my_path, ld_library_path);
00380
00381 if (ld_libraryn32_path)
00382 asprintf(&l32_path, "%s:%s", my_path,
00383 ld_libraryn32_path);
00384
00385 my_putenv("LD_LIBRARY_PATH", l_path);
00386 my_putenv("LD_LIBRARYN32_PATH", l32_path);
00387
00388
00389
00390 nls_path = getenv("NLSPATH");
00391 env_path = get_phase_dir(P_f90_fe);
00392
00393 if (nls_path) {
00394 my_putenv("NLSPATH", "%s:%s/%%N.cat", nls_path, env_path);
00395 } else {
00396 my_putenv("NLSPATH", "%s/%%N.cat", env_path);
00397 }
00398
00399 if (uses_message_system && getenv("ORIG_CMD_NAME") == NULL)
00400 my_putenv("ORIG_CMD_NAME", "%s", program_name);
00401
00402 if (phase == P_f90_fe) {
00403 char *root;
00404 char *modulepath;
00405 int len;
00406 char *new_env;
00407 char *env_name = "FORTRAN_SYSTEM_MODULES=";
00408 char *env_val = "/usr/lib/f90modules";
00409 root = getenv("TOOLROOT");
00410 if (root != NULL) {
00411 len = strlen(env_val) + strlen(root) +3 + strlen(env_val);
00412 new_env = alloca(len);
00413 sprintf(new_env,"%s/%s:%s",root,env_val,env_val);
00414 env_val = new_env;
00415 }
00416 modulepath = string_copy(getenv("FORTRAN_SYSTEM_MODULES"));
00417 if (modulepath != NULL) {
00418
00419 if (modulepath[strlen(modulepath)-1] == ':') {
00420
00421 len = strlen(modulepath) + strlen(env_val) + 1;
00422 new_env = alloca(len);
00423 sprintf(new_env,"%s%s",modulepath,env_val);
00424 } else {
00425
00426 len = strlen(modulepath) + strlen(env_val) + 2;
00427 new_env = alloca(len);
00428 sprintf(new_env,"%s:%s",modulepath,env_val);
00429 }
00430 env_val = new_env;
00431 }
00432
00433 my_putenv ("FORTRAN_SYSTEM_MODULES", "%s", env_val);
00434 }
00435
00436
00437
00438 #ifdef KEY // gcc will invoke the cc1 in the COMPILER_PATH directory,
00439
00440
00441 if (!is_matching_phase(get_phase_mask(P_any_cpp), phase))
00442 #endif
00443 my_putenv ("COMPILER_PATH", "%s", get_phase_dir(P_collect));
00444
00445
00446
00447
00448
00449 my_putenv ("COMPILER_BIN", "%s/" BINPATH "/" OPEN64_NAME_PREFIX "cc", global_toolroot);
00450 my_execv(name, argv);
00451 } else {
00452
00453 int procid;
00454 while ((waitpid = wait (&waitstatus)) != forkpid) {
00455 if (waitpid == -1) {
00456 error("bad return from wait");
00457 cleanup();
00458 do_exit(RC_SYSTEM_ERROR);
00459
00460 }
00461 }
00462 if (time_flag) print_time(name);
00463
00464 if (WIFSTOPPED(waitstatus)) {
00465 termsig = WSTOPSIG(waitstatus);
00466 error("STOPPED signal received from %s", name);
00467 cleanup();
00468 do_exit(RC_SYSTEM_ERROR);
00469
00470 } else if (WIFEXITED(waitstatus)) {
00471 int status = WEXITSTATUS(waitstatus);
00472 extern int inline_t;
00473 boolean internal_err = FALSE;
00474 boolean user_err = FALSE;
00475
00476 if (phase == P_prof) {
00477
00478
00479 if (prof_file != NULL) {
00480 if (!(stat(fb_file, &stat_buf) != 0 && errno == ENOENT))
00481 status = RC_OKAY;
00482 } else {
00483 internal_error("No count file was specified for a prof run");
00484 perror(program_name);
00485 }
00486 }
00487
00488 if (phase == P_f90_fe && keep_listing) {
00489 char *cif_file;
00490 cif_file = construct_given_name(
00491 drop_path(source_file), "T", TRUE);
00492 if (!(stat(cif_file, &stat_buf) != 0 && errno == ENOENT))
00493 f90_fe_status = status;
00494 f90_fe_name = string_copy(name);
00495
00496
00497
00498
00499
00500
00501
00502 status = RC_OKAY;
00503 }
00504
00505 if (phase == P_lister) {
00506 if (status == RC_OKAY && f90_fe_status != RC_OKAY) {
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516 status = f90_fe_status;
00517 name = string_copy(f90_fe_name);
00518
00519
00520
00521
00522
00523 f90_fe_status = RC_OKAY;
00524 }
00525 }
00526
00527 switch (status) {
00528 case RC_OKAY:
00529 #ifdef KEY
00530
00531
00532
00533 if (inline_t != UNDEFINED) {
00534 run_inline = inline_t;
00535 break;
00536 }
00537
00538
00539 if (gnu_major_version == 4) {
00540 if (is_matching_phase(get_phase_mask(phase),
00541 P_wgen)) {
00542 run_inline = FALSE;
00543 }
00544 break;
00545 }
00546 #endif
00547 if (inline_t == UNDEFINED
00548 && is_matching_phase(
00549 get_phase_mask(phase), P_any_fe) )
00550 {
00551 #ifdef KEY
00552 run_inline = FALSE;
00553 #else
00554 inline_t = FALSE;
00555 #endif
00556 }
00557 break;
00558 case RC_NEED_INLINER:
00559 #ifdef KEY // If the command line has explicit inline
00560
00561
00562 if (inline_t != UNDEFINED) {
00563 run_inline = inline_t;
00564 break;
00565 }
00566
00567
00568 if (gnu_major_version == 4) {
00569 if (is_matching_phase(get_phase_mask(phase),
00570 P_wgen)) {
00571 run_inline = TRUE;
00572 }
00573 break;
00574 }
00575 #endif
00576 if (inline_t == UNDEFINED
00577 && is_matching_phase(
00578 get_phase_mask(phase), P_any_fe) )
00579 {
00580 #ifdef KEY
00581 run_inline = TRUE;
00582 #else
00583 inline_t = TRUE;
00584 #endif
00585 }
00586
00587 break;
00588
00589 case RC_USER_ERROR:
00590 case RC_NORECOVER_USER_ERROR:
00591 case RC_SYSTEM_ERROR:
00592 case RC_GCC_ERROR:
00593 user_err = TRUE;
00594 break;
00595
00596 case RC_OVERFLOW_ERROR:
00597 if (!ran_twice && phase == P_be) {
00598
00599 ran_twice = TRUE;
00600 add_string (args, "-TENV:long_eh_offsets");
00601 add_string (args, "-TENV:large_stack");
00602 run_phase (phase, name, args);
00603 return;
00604 }
00605 internal_err = TRUE;
00606 break;
00607 #ifdef KEY
00608 case RC_GCC_INTERNAL_ERROR:
00609 #endif
00610 case RC_INTERNAL_ERROR:
00611 internal_err = TRUE;
00612 break;
00613 default:
00614 internal_err = TRUE;
00615 break;
00616 }
00617 if (internal_err) {
00618 if (phase == P_ld || phase == P_ldplus ||
00619 #ifdef KEY
00620 phase == P_gas ||
00621 phase == P_f_coco ||
00622 phase == P_spin_cc1 ||
00623 phase == P_spin_cc1plus ||
00624 status == RC_GCC_INTERNAL_ERROR ||
00625 #endif
00626 phase == P_gcpp || phase == P_gcpp_plus) {
00627 if (phase == P_gas ||
00628 status == RC_GCC_INTERNAL_ERROR) {
00629 internal_error_occurred = 1;
00630 }
00631 log_error("%s returned non-zero status %d",
00632 name, status);
00633 nomsg_error(status);
00634 } else {
00635 internal_error("%s returned non-zero status %d",
00636 name, status);
00637 }
00638 }
00639 else if (user_err) {
00640
00641 if (phase == P_c_gfe || phase == P_cplus_gfe
00642 #ifdef KEY
00643 || phase == P_wgen
00644 || phase == P_spin_cc1
00645 || phase == P_spin_cc1plus
00646 #endif
00647 ) {
00648 nomsg_error(RC_INTERNAL_ERROR);
00649 }
00650 else if (!show_flag || save_stderr) {
00651 nomsg_error(RC_USER_ERROR);
00652 } else {
00653 error("%s returned non-zero status %d",
00654 name, status);
00655 }
00656 }
00657 ran_twice = FALSE;
00658 return;
00659 } else if(WIFSIGNALED(waitstatus)){
00660 termsig = WTERMSIG(waitstatus);
00661 switch (termsig) {
00662 case SIGHUP:
00663 case SIGINT:
00664 case SIGQUIT:
00665 case SIGKILL:
00666 case SIGTERM:
00667 error("%s died due to signal %d", name, termsig);
00668 break;
00669 default:
00670 internal_error("%s died due to signal %d",
00671 name, termsig);
00672 break;
00673 }
00674 if(WCOREDUMP(waitstatus)) {
00675 error("core dumped");
00676 }
00677 if (termsig == SIGKILL) {
00678 error("Probably caused by running out of swap space -- check %s", LOGFILE);
00679 }
00680 cleanup();
00681 do_exit(RC_SYSTEM_ERROR);
00682 } else {
00683
00684 internal_error("driver exec'ing is confused");
00685 return;
00686 }
00687 }
00688
00689 #else
00690
00691 if (input != NULL) {
00692 if ((fdin = open (input, O_RDONLY)) == -1) {
00693 error ("cannot open input file %s", input);
00694 cleanup ();
00695 exit (RC_SYSTEM_ERROR);
00696
00697 }
00698 dup2 (fdin, fileno(stdin));
00699 }
00700 if (output != NULL) {
00701 if ((fdout = creat (output, 0666)) == -1) {
00702 error ("cannot create output file %s", output);
00703 cleanup ();
00704 exit (RC_SYSTEM_ERROR);
00705
00706 }
00707 if (save_stderr) {
00708 dup2 (fdout, fileno(stderr));
00709 } else {
00710 dup2 (fdout, fileno(stdout));
00711 }
00712 }
00713
00714 rld_path = get_phase_ld_library_path (phase);
00715
00716 if (rld_path != 0) {
00717 string new_env;
00718 string env_name = "LD_LIBRARY_PATH";
00719 int len = strlen (env_name) + strlen(rld_path) + 2;
00720 if (ld_library_path) {
00721 len += strlen (ld_library_path) + 1;
00722 new_env = alloca (len);
00723 sprintf (new_env, "%s=%s:%s", env_name, rld_path,
00724 ld_library_path);
00725 } else {
00726 new_env = alloca (len);
00727 sprintf (new_env, "%s=%s", env_name, rld_path);
00728 }
00729 putenv (new_env);
00730 }
00731
00732 {
00733 unsigned int total_bytes = 0;
00734 int i;
00735 char *argv_str, *new_a;
00736 STARTUPINFO si;
00737 PROCESS_INFORMATION pi;
00738 DWORD exit_code;
00739 int spawnRet;
00740
00741 ZeroMemory( &si, sizeof(si) );
00742 si.cb = sizeof(si);
00743 ZeroMemory( &pi, sizeof(pi) );
00744
00745
00746
00747
00748
00749
00750 for (i = 0; i < argc; i++)
00751 total_bytes += (2 * strlen (argv[i])) + 3;
00752 argv_str = malloc (total_bytes);
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772 new_a = argv_str;
00773 for (i = 0; i < argc; i++) {
00774 int nback;
00775 char *p = NULL;
00776 const char *a = argv[i];
00777 int len = strlen (a);
00778 if (len != 0 && !strpbrk (a, " \t\n\r\"")) {
00779 memcpy (new_a, a, len);
00780 new_a += len;
00781 } else {
00782 *new_a++ = '"';
00783
00784
00785
00786
00787
00788
00789
00790
00791 for (; (p = strpbrk (a, "\"\\")); a = ++p) {
00792 memcpy (new_a, a, p - a);
00793 new_a += (p - a);
00794
00795 nback = strspn (p, "\\");
00796 if (nback == 0) {
00797
00798
00799 *new_a++ = '\\';
00800 *new_a++ = '"';
00801 } else {
00802
00803 memcpy (new_a, p, nback);
00804 new_a += nback;
00805
00806
00807 if (!p[nback] || p[nback] == '"') {
00808 memcpy (new_a, p, nback);
00809 new_a += nback;
00810 }
00811
00812 p += nback - 1;
00813 }
00814 }
00815 if (*a) {
00816 len = strlen (a);
00817 memcpy (new_a, a, len);
00818 new_a += len;
00819 }
00820 *new_a++ = '"';
00821 }
00822 if (i == argc - 1)
00823 *new_a++ = '\0';
00824 else
00825 *new_a++ = ' ';
00826 }
00827
00828 spawnRet = CreateProcess(NULL, argv_str, NULL, NULL,
00829 TRUE, 0, NULL, NULL, &si, &pi);
00830 if (time_flag) print_time(name);
00831 if (spawnRet == 0) {
00832
00833 switch(GetLastError())
00834 {
00835 case E2BIG:
00836 error("Spawn:Too many arguments\n");
00837 break;
00838 case EINVAL:
00839 error("Spawn:Invalid mode\n");
00840 break;
00841 case ENOENT:
00842 error("Spawn: File/Path not found\n");
00843 break;
00844 case ENOEXEC:
00845 error("Spawn: Bad executable file\n");
00846 break;
00847 case ENOMEM:
00848 error("Spawn: Not enough memory\n");
00849 break;
00850 default:
00851 error("Could not create process %s. Windows error code %d\n", argv_str, GetLastError());
00852 }
00853
00854 cleanup ();
00855 exit (RC_SYSTEM_ERROR);
00856
00857 }
00858 WaitForSingleObject(pi.hProcess, INFINITE);
00859 GetExitCodeProcess(pi.hProcess, &exit_code);
00860 CloseHandle(pi.hProcess);
00861 CloseHandle(pi.hThread);
00862
00863 if (exit_code == 0 || exit_code < -1) {
00864
00865 int status = exit_code;
00866 extern int inline_t;
00867 boolean_t internal_err = FALSE;
00868 boolean_t user_err = FALSE;
00869
00870 switch (status) {
00871
00872 case RC_OKAY:
00873 if (inline_t == UNDEFINED &&
00874 is_matching_phase(get_phase_mask(phase), P_any_fe))
00875 inline_t = FALSE;
00876 break;
00877
00878 case RC_NEED_INLINER:
00879 if (inline_t == UNDEFINED &&
00880 is_matching_phase(get_phase_mask(phase), P_any_fe))
00881 inline_t = TRUE;
00882
00883 break;
00884
00885 case RC_USER_ERROR:
00886 case RC_NORECOVER_USER_ERROR:
00887 case RC_SYSTEM_ERROR:
00888 case RC_GCC_ERROR:
00889 user_err = TRUE;
00890 break;
00891
00892 case RC_OVERFLOW_ERROR:
00893 if (!ran_twice && phase == P_be) {
00894
00895 ran_twice = TRUE;
00896 add_string (args, "-TENV:long_eh_offsets");
00897 add_string (args, "-TENV:large_stack");
00898 run_phase (phase, name, args);
00899 return;
00900 }
00901 internal_err = TRUE;
00902 break;
00903
00904 case RC_INTERNAL_ERROR:
00905 if (phase == P_ld || phase == P_ldplus)
00906
00907 user_err = TRUE;
00908 else
00909 internal_err = TRUE;
00910 break;
00911
00912 default:
00913 if (phase == P_c_gfe || phase == P_cplus_gfe)
00914 user_err = TRUE;
00915 else
00916 internal_err = TRUE;
00917 break;
00918 }
00919
00920 if (internal_err) {
00921 error("%s returned non-zero status %d", name, status);
00922 }
00923 else if (user_err) {
00924
00925 if (!show_flag || save_stderr)
00926 nomsg_error(RC_USER_ERROR);
00927 else
00928 error("%s returned non-zero status %d", name, status);
00929 }
00930 ran_twice = FALSE;
00931 return;
00932 }
00933 else {
00934
00935
00936
00937 error("error from spawn");
00938 cleanup ();
00939 exit (RC_SYSTEM_ERROR);
00940
00941 }
00942 }
00943
00944 #endif
00945 }
00946
00947
00948
00949
00950 void
00951 handler (int sig)
00952 {
00953 #ifndef __MINGW32__
00954 error("signal %s caught, stop processing", strsignal(sig));
00955 #else
00956 error("signal %d caught, stop processing", sig);
00957 #endif
00958 cleanup ();
00959 do_exit (RC_SYSTEM_ERROR);
00960 }
00961
00962
00963 void
00964 catch_signals (void)
00965 {
00966
00967 #ifndef __MINGW32__
00968 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
00969 signal (SIGHUP, handler);
00970 if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
00971 signal (SIGQUIT, handler);
00972 if (signal (SIGBUS, SIG_IGN) != SIG_IGN)
00973 signal (SIGBUS, handler);
00974 if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
00975 signal (SIGPIPE, handler);
00976 if (signal (SIGTRAP, SIG_IGN) != SIG_IGN)
00977 signal (SIGTRAP, handler);
00978 #endif
00979 if (signal (SIGILL, SIG_IGN) != SIG_IGN)
00980 signal (SIGILL, handler);
00981 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
00982 signal (SIGINT, handler);
00983 if (signal (SIGABRT, SIG_IGN) != SIG_IGN)
00984 signal (SIGABRT, handler);
00985 if (signal (SIGFPE, SIG_IGN) != SIG_IGN)
00986 signal (SIGFPE, handler);
00987 if (signal (SIGSEGV, SIG_IGN) != SIG_IGN)
00988 signal (SIGSEGV, handler);
00989 if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
00990 signal (SIGTERM, handler);
00991 }
00992
00993 #ifndef __MINGW32__
00994
00995
00996 clock_t time0;
00997 struct tms tm0;
00998
00999 static void
01000 init_time (void)
01001 {
01002 time0 = times (&tm0);
01003 }
01004
01005
01006 static void
01007 print_time (char *phase)
01008 {
01009 clock_t time1, wtime;
01010 double utime, stime;
01011 struct tms tm1;
01012
01013 #ifndef HZ
01014 long HZ = sysconf(_SC_CLK_TCK);
01015 #endif
01016
01017 time1 = times (&tm1);
01018 utime = (double)(tm1.tms_utime + tm1.tms_cutime -
01019 tm0.tms_utime - tm0.tms_cutime) / (double)HZ;
01020 stime = (double)(tm1.tms_stime + tm1.tms_cstime -
01021 tm0.tms_stime - tm0.tms_cstime) / (double)HZ;
01022 wtime = time1 - time0;
01023
01024 fprintf (stderr, "%s phase time: %.2fu %.2fs %lu:%04.1f %.0f%%\n",
01025 phase, utime, stime, wtime / (60*HZ),
01026 (double)(wtime % (60*HZ)) / (double)HZ,
01027 (utime + stime) / ((double)wtime / (double)HZ) * 100.0);
01028 }
01029
01030 #else
01031
01032 #ifndef HZ
01033 #define HZ 100
01034 #endif
01035 time_t time0;
01036
01037 static void
01038 init_time (void)
01039 {
01040 time0 = time (NULL);
01041 }
01042
01043 static void
01044 print_time (string phase)
01045 {
01046 time_t time1, wtime;
01047
01048
01049
01050 time1 = time(NULL);
01051 wtime = difftime(time1,time0);
01052
01053 fprintf (stderr, "%s phase time: %u:%04.1f\n",
01054 phase, wtime / (60*HZ),
01055 (double)(wtime % (60*HZ)) / (double)HZ);
01056 }
01057
01058 #endif