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 <string.h>
00047 #include <sys/stat.h>
00048 #include <sys/types.h>
00049 #if defined(_WIN32)
00050 #include <io.h>
00051 #else
00052 #include <sys/utsname.h>
00053 #endif
00054 #include <time.h>
00055 #include <unistd.h>
00056 #include <errno.h>
00057 #include "phases.h"
00058 #include "lang_defs.h"
00059 #include "string_utils.h"
00060 #include "file_names.h"
00061 #include "file_utils.h"
00062 #include "errors.h"
00063 #include "opt_actions.h"
00064 #include "option_seen.h"
00065 #include "option_names.h"
00066 #include "run.h"
00067 #include "version.h"
00068
00069 extern int errno;
00070
00071 boolean keep_flag = FALSE;
00072
00073 string_list_t *count_files = NULL;
00074 static string_list_t *temp_files = NULL;
00075 #ifdef KEY
00076 string_list_t *isystem_dirs = NULL;
00077 #endif
00078 static char *tmpdir;
00079 static char *saved_object = NULL;
00080
00081 #if !defined(_WIN32)
00082 #define DEFAULT_TMPDIR "/tmp"
00083
00084 #else
00085
00086 #include <windows.h>
00087 #define DEFAULT_TMPDIR default_tmpdir()
00088
00089 static char *
00090 conv_dir_seperator_to_posix (char *bad_path)
00091 {
00092 int i;
00093 int bad_path_len = strlen(bad_path);
00094 for (i = bad_path_len; i-1 >= 0; i--)
00095 if(bad_path[i] == '\\')
00096
00097 bad_path[i] = '/';
00098 return bad_path;
00099 }
00100
00101 static char *
00102 conv_dir_seperator_to_win32 (char *bad_path)
00103 {
00104 int i;
00105 int bad_path_len = strlen(bad_path);
00106 for (i = bad_path_len; i-1 >= 0; i--)
00107 if(bad_path[i] == '/')
00108
00109 bad_path[i] = '\\';
00110 return bad_path;
00111 }
00112
00113 static char * default_tmpdir(void)
00114 {
00115 static char dir[MAX_PATH];
00116 if (GetTempPath(MAX_PATH, (LPSTR)dir) == 0)
00117 return "";
00118 conv_dir_seperator_to_posix(dir);
00119 return (char*) dir;
00120 }
00121 #endif
00122
00123 static string_pair_list_t *temp_obj_files = NULL;
00124
00125
00126
00127 char *
00128 get_object_file (char *src)
00129 {
00130 #if defined(_WIN32) || defined(TARG_NVISA)
00131
00132
00133 #else
00134
00135
00136 if (!(keep_flag || (ipa == TRUE) || remember_last_phase == P_any_as)) {
00137 char *obj_name = change_suffix(src, "o");
00138 string_pair_item_t *p;
00139 buffer_t buf;
00140 char *mapped_name;
00141 FOREACH_STRING_PAIR (p, temp_obj_files) {
00142 if (strcmp (STRING_PAIR_KEY(p), obj_name) == 0)
00143 return STRING_PAIR_VAL(p);
00144 }
00145
00146 sprintf(buf, "cco.");
00147 mapped_name = tempnam (tmpdir, buf);
00148 add_string_pair (temp_obj_files, obj_name, mapped_name);
00149 return mapped_name;
00150 }
00151
00152
00153
00154
00155 if (ipa == TRUE &&
00156 !option_was_seen(O_c) &&
00157 keep_flag != TRUE) {
00158 char *p;
00159 src = strdupa(src);
00160 for (p = src; *p != '\0'; p++) {
00161 if (*p == '/')
00162 *p = '%';
00163 }
00164 }
00165 #endif
00166 return change_suffix(drop_path(src), "o");
00167 }
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 char *
00179 create_temp_file_name (char *suffix)
00180 {
00181 buffer_t buf;
00182 buffer_t pathbuf;
00183 size_t prefix_len;
00184 char *s;
00185 string_item_t *p;
00186 int fd;
00187
00188
00189 sprintf(buf, "cc%s#.XXXXXX", suffix);
00190 sprintf(pathbuf, "%s/%s", tmpdir, buf);
00191 #ifdef _WIN32
00192
00193
00194 conv_dir_seperator_to_posix(pathbuf);
00195 #endif
00196
00197 prefix_len = strlen(pathbuf) - strlen(strchr(pathbuf, '#'));
00198
00199 for (p = temp_files->head; p != NULL; p = p->next) {
00200 if (strncmp(p->name, pathbuf, prefix_len) == 0) {
00201
00202 return p->name;
00203 }
00204 }
00205
00206 #ifdef _WIN32
00207
00208 s = mktemp (pathbuf);
00209 if (!s)
00210 internal_error("Couldn't create temporary file %s\n", pathbuf);
00211
00212 s = conv_dir_seperator_to_posix(s);
00213 s = string_copy(s);
00214 #else
00215 fd = mkstemp(pathbuf);
00216 s = string_copy(pathbuf);
00217 #endif
00218 add_string (temp_files, s);
00219 return s;
00220 }
00221
00222 char *
00223 construct_name (char *src, char *suffix)
00224 {
00225 if (keep_flag || current_phase == remember_last_phase) {
00226 char *srcname;
00227
00228
00229
00230
00231
00232 if (outfile && option_was_seen(O_c) && get_suffix(outfile))
00233 srcname = outfile;
00234 else
00235 srcname = src;
00236 return change_suffix(drop_path(srcname), suffix);
00237 } else {
00238 return create_temp_file_name (suffix);
00239 }
00240 }
00241
00242
00243 char *
00244 construct_given_name (char *src, char *suffix, boolean keep)
00245 {
00246 char *s;
00247 s = change_suffix(drop_path(src), suffix);
00248 if (keep || current_phase == remember_last_phase) {
00249 return s;
00250 } else {
00251 s = string_copy(s);
00252 add_string_if_new (temp_files, s);
00253 return s;
00254 }
00255 }
00256
00257 void
00258 mark_saved_object_for_cleanup ( void )
00259 {
00260 if (saved_object != NULL)
00261 add_string_if_new (temp_files, saved_object);
00262 }
00263
00264
00265 char *
00266 construct_file_with_extension (char *src, char *ext)
00267 {
00268 return change_suffix(drop_path(src),ext);
00269 }
00270
00271 void
00272 init_temp_files (void)
00273 {
00274 #if defined(_WIN32)
00275 tmpdir = getenv("TMP");
00276 if (tmpdir == NULL) {
00277 tmpdir = getenv("TMPDIR");
00278 }
00279 #else
00280 tmpdir = string_copy(getenv("TMPDIR"));
00281 #endif
00282 if (tmpdir == NULL) {
00283 tmpdir = DEFAULT_TMPDIR;
00284 }
00285 #if defined(_WIN32)
00286
00287 {
00288 static char buf[1024];
00289 GetShortPathName(tmpdir, buf, 1024);
00290 tmpdir = buf;
00291 }
00292 #endif
00293 if (!is_directory(tmpdir)) {
00294 error("$TMPDIR does not exist: %s", tmpdir);
00295 }
00296 else if (!directory_is_writable(tmpdir)) {
00297 error("$TMPDIR not writable: %s", tmpdir);
00298 }
00299 else if (is_dir_separator(tmpdir[strlen(tmpdir)-1])) {
00300
00301 tmpdir[strlen(tmpdir)-1] = '\0';
00302 }
00303 temp_files = init_string_list();
00304
00305 temp_obj_files = init_string_pair_list();
00306 }
00307
00308 void
00309 init_count_files (void)
00310 {
00311 count_files = init_string_list();
00312 }
00313
00314 static char *report_file;
00315
00316 void
00317 init_crash_reporting (void)
00318 {
00319 #if !defined(_WIN32)
00320
00321 #ifdef PSC_TO_OPEN64
00322 if ((report_file = getenv("OPEN64_CRASH_REPORT")) != NULL)
00323 #endif
00324 goto bail;
00325
00326 #ifdef PSC_TO_OPEN64
00327 if (asprintf(&report_file, "%s/open64_crash_XXXXXX", tmpdir) == -1) {
00328 #endif
00329 report_file = NULL;
00330 goto bail;
00331 }
00332
00333 if (mkstemp(report_file) == -1) {
00334 report_file = NULL;
00335 goto bail;
00336 }
00337
00338 #ifdef PSC_TO_OPEN64
00339 setenv("OPEN64_CRASH_REPORT", report_file, 1);
00340 #endif
00341 bail:
00342 #endif
00343 return;
00344 }
00345
00346 static int save_count;
00347
00348 static int
00349 save_cpp_output (char *path)
00350 {
00351 char *save_dir, *save_path, *final_path;
00352 FILE *ifp = NULL, *ofp = NULL;
00353 char *name = drop_path(path);
00354 int saved = 0;
00355 #if !defined(_WIN32)
00356
00357
00358
00359
00360 struct utsname uts;
00361 char buf[4096];
00362 size_t nread;
00363 char *suffix;
00364 char *home;
00365 time_t now;
00366 int i;
00367
00368 if (strncmp(name, "cci.", 4) == 0)
00369 suffix = ".i";
00370 else if (strncmp(name, "ccii.", 5) == 0)
00371 suffix = ".ii";
00372 else
00373 goto bail;
00374
00375 if ((ifp = fopen(path, "r")) == NULL)
00376 goto bail;
00377
00378 #ifdef PSC_TO_OPEN64
00379 if ((save_dir = getenv("OPEN64_PROBLEM_REPORT_DIR")) == NULL &&
00380 (home = getenv("HOME")) != NULL) {
00381 asprintf(&save_dir, "%s/.open64-bugs", home);
00382 }
00383 #endif
00384
00385 if (save_dir && mkdir(save_dir, 0700) == -1 && errno != EEXIST) {
00386 save_dir = NULL;
00387 }
00388
00389 if (save_dir == NULL) {
00390 save_dir = tmpdir;
00391 }
00392
00393 asprintf(&save_path, "%s/%s_error_XXXXXX", save_dir, program_name);
00394
00395 if (mkstemp(save_path) == -1) {
00396 goto b0rked;
00397 }
00398
00399 if ((ofp = fopen(save_path, "w")) == NULL) {
00400 goto b0rked;
00401 }
00402
00403 now = time(NULL);
00404 #ifdef PSC_TO_OPEN64
00405 fprintf(ofp, "/*\n\nOpen64 compiler problem report - %s",
00406 ctime(&now));
00407 fprintf(ofp, "Please report this problem to http://bugs.open64.net/\n");
00408 #endif
00409 fprintf(ofp, "If possible, please attach a copy of this file with your "
00410 "report.\n");
00411 fprintf(ofp, "\nPLEASE NOTE: This file contains a preprocessed copy of the "
00412 "source file\n"
00413 "that may have led to this problem occurring.\n");
00414
00415 uname(&uts);
00416 fprintf(ofp, "\nCompiler command line (%s ABI used on %s system):\n",
00417 abi == ABI_N32 ? "32-bit" : "64-bit",
00418 uts.machine);
00419
00420 fprintf(ofp, " ");
00421 for (i = 0; i < saved_argc; ++i)
00422 if (saved_argv[i] &&
00423 strcmp(saved_argv[i], "-default_options") != 0) {
00424 int len;
00425 len = quote_shell_arg(saved_argv[i], buf);
00426 buf[len] = '\0';
00427 fprintf(ofp, " %s", buf);
00428 }
00429 fprintf(ofp, "\n\n");
00430
00431 fprintf(ofp, "Version %s build information:\n",
00432 compiler_version);
00433 fprintf(ofp, " Changeset %s\n", cset_id);
00434 fprintf(ofp, " Built by %s@%s in %s\n", build_user,
00435 build_host, build_root);
00436 fprintf(ofp, " Build date %s\n", build_date);
00437
00438 if (report_file) {
00439 int newline = 1;
00440 struct stat st;
00441 FILE *rfp;
00442
00443 if (stat(report_file, &st) == -1)
00444 goto no_report;
00445
00446 if (st.st_size == 0)
00447 goto no_report;
00448
00449 fprintf(ofp, "\nDetailed problem report:\n");
00450 if ((rfp = fopen(report_file, "r")) == NULL) {
00451 goto no_report;
00452 }
00453
00454 while (fgets(buf, sizeof(buf), rfp) != NULL) {
00455 int len = strlen(buf);
00456 if (newline)
00457 fputs(" ", ofp);
00458 fputs(buf, ofp);
00459 newline = buf[len - 1] == '\n';
00460 }
00461 if (!newline)
00462 putc('\n', ofp);
00463
00464 fclose(rfp);
00465 }
00466
00467 no_report:
00468 if (string_list_size(error_list)) {
00469 string_item_t *i;
00470 fprintf(ofp, "\nInformation from compiler driver:\n");
00471 FOREACH_STRING(i, error_list) {
00472 fprintf(ofp, " %s\n", STRING_NAME(i));
00473 }
00474 }
00475
00476 fprintf(ofp, "\nThe remainder of this file contains a preprocessed copy of "
00477 "the\n"
00478 "source file that appears to have led to this problem.\n\n*/\n");
00479
00480 while ((nread = fread(buf, 1, sizeof(buf), ifp)) > 0) {
00481 size_t nwrit;
00482 if ((nwrit = fwrite(buf, 1, nread, ofp)) < nread) {
00483 if (nwrit != 0)
00484 errno = EFBIG;
00485 goto b0rked;
00486 }
00487 }
00488
00489 #ifdef PSC_TO_OPEN64
00490 fprintf(ofp, "\n/* End of Open64 compiler problem report. */\n");
00491 #endif
00492
00493 asprintf(&final_path, "%s%s", save_path, suffix);
00494 rename(save_path, final_path);
00495
00496 if (save_count == 0) {
00497 #ifdef PSC_TO_OPEN64
00498 fprintf(stderr, "Please report this problem to "
00499 "http://bugs.open64.net/\n");
00500 #endif
00501 }
00502
00503 fprintf(stderr, "Problem report saved as %s\n", final_path);
00504 save_count++;
00505 saved = 1;
00506
00507 goto bail;
00508 #endif
00509
00510 b0rked:
00511 fprintf(stderr, "Could not save problem report to %s: %s\n",
00512 save_path, strerror(errno));
00513 bail:
00514 if (ifp != NULL)
00515 fclose(ifp);
00516 if (ofp != NULL)
00517 fclose(ofp);
00518
00519 return saved;
00520 }
00521
00522 void
00523 cleanup (void)
00524 {
00525
00526 string_item_t *p;
00527 int status;
00528 if (temp_files == NULL) return;
00529 for (p = temp_files->head; p != NULL; p = p->next) {
00530 if (debug) printf("unlink %s\n", p->name);
00531
00532
00533 if (internal_error_occurred)
00534 save_cpp_output(p->name);
00535 #if !defined(_WIN32)
00536 status = unlink(p->name);
00537 #else
00538
00539
00540
00541 conv_dir_seperator_to_win32(p->name);
00542 status = unlink(p->name);
00543 conv_dir_seperator_to_posix(p->name);
00544 #endif
00545 if (status != 0 && errno != ENOENT) {
00546 internal_error("cannot unlink temp file %s", p->name);
00547 perror(program_name);
00548 }
00549 }
00550 temp_files->head = temp_files->tail = NULL;
00551
00552 if (save_count) {
00553 fprintf(stderr, "Please review the above file%s and, "
00554 "if possible, attach %s to your problem report.\n",
00555 save_count == 1 ? "" : "s",
00556 save_count == 1 ? "it" : "them");
00557 }
00558 }
00559
00560 void
00561 mark_for_cleanup (char *s)
00562 {
00563 add_string_if_new (temp_files, s);
00564 }
00565
00566 void
00567 cleanup_temp_objects ()
00568 {
00569
00570 string_pair_item_t *p;
00571 FOREACH_STRING_PAIR (p, temp_obj_files) {
00572 char *s = STRING_PAIR_VAL(p);
00573 int status = unlink (s);
00574 if (status != 0 && errno != ENOENT) {
00575 internal_error("cannot unlink temp object file %s", s);
00576 perror(program_name);
00577 }
00578 }
00579 if (report_file) {
00580 unlink(report_file);
00581 }
00582 }
00583
00584 #ifdef KEY
00585 char *
00586 get_report_file_name() {
00587 return report_file;
00588 }
00589 #endif