|
|
1.1 ! root 1: /* tmp.c */ ! 2: ! 3: /* Author: ! 4: * Steve Kirkendall ! 5: * 14407 SW Teal Blvd. #C ! 6: * Beaverton, OR 97005 ! 7: * [email protected] ! 8: */ ! 9: ! 10: ! 11: /* This file contains functions which create & readback a TMPFILE */ ! 12: ! 13: ! 14: #include "config.h" ! 15: #include "vi.h" ! 16: #if TOS ! 17: # include <stat.h> ! 18: #else ! 19: # if OSK ! 20: # include "osk.h" ! 21: # else ! 22: # if AMIGA ! 23: # include "amistat.h" ! 24: # else ! 25: # include <sys/stat.h> ! 26: # endif ! 27: # endif ! 28: #endif ! 29: #if TURBOC ! 30: # include <process.h> ! 31: #endif ! 32: ! 33: #ifndef NO_MODELINES ! 34: static void do_modelines(l, stop) ! 35: long l; /* line number to start at */ ! 36: long stop; /* line number to stop at */ ! 37: { ! 38: char *str; /* used to scan through the line */ ! 39: char *start; /* points to the start of the line */ ! 40: char buf[80]; ! 41: ! 42: /* if modelines are disabled, then do nothing */ ! 43: if (!*o_modelines) ! 44: { ! 45: return; ! 46: } ! 47: ! 48: /* for each line... */ ! 49: for (; l <= stop; l++) ! 50: { ! 51: /* for each position in the line.. */ ! 52: for (str = fetchline(l); *str; str++) ! 53: { ! 54: /* if it is the start of a modeline command... */ ! 55: if ((str[0] == 'e' && str[1] == 'x' ! 56: || str[0] == 'v' && str[1] == 'i') ! 57: && str[2] == ':') ! 58: { ! 59: start = str += 3; ! 60: ! 61: /* find the end */ ! 62: for (str = start + strlen(start); *--str != ':'; ) ! 63: { ! 64: } ! 65: ! 66: /* if it is a well-formed modeline, execute it */ ! 67: if (str > start && str - start < sizeof buf) ! 68: { ! 69: strncpy(buf, start, (int)(str - start)); ! 70: exstring(buf, str - start, '\\'); ! 71: break; ! 72: } ! 73: } ! 74: } ! 75: } ! 76: } ! 77: #endif ! 78: ! 79: ! 80: /* The FAIL() macro prints an error message and then exits. */ ! 81: #define FAIL(why,arg) mode = MODE_EX; msg(why, arg); endwin(); exit(9) ! 82: ! 83: /* This is the name of the temp file */ ! 84: static char tmpname[80]; ! 85: ! 86: /* This function creates the temp file and copies the original file into it. ! 87: * Returns if successful, or stops execution if it fails. ! 88: */ ! 89: int tmpstart(filename) ! 90: char *filename; /* name of the original file */ ! 91: { ! 92: int origfd; /* fd used for reading the original file */ ! 93: struct stat statb; /* stat buffer, used to examine inode */ ! 94: REG BLK *this; /* pointer to the current block buffer */ ! 95: REG BLK *next; /* pointer to the next block buffer */ ! 96: int inbuf; /* number of characters in a buffer */ ! 97: int nread; /* number of bytes read */ ! 98: REG int j, k; ! 99: int i; ! 100: long nbytes; ! 101: ! 102: /* switching to a different file certainly counts as a change */ ! 103: changes++; ! 104: redraw(MARK_UNSET, FALSE); ! 105: ! 106: /* open the original file for reading */ ! 107: *origname = '\0'; ! 108: if (filename && *filename) ! 109: { ! 110: strcpy(origname, filename); ! 111: origfd = open(origname, O_RDONLY); ! 112: if (origfd < 0 && errno != ENOENT) ! 113: { ! 114: msg("Can't open \"%s\"", origname); ! 115: return tmpstart(""); ! 116: } ! 117: if (origfd >= 0) ! 118: { ! 119: if (stat(origname, &statb) < 0) ! 120: { ! 121: FAIL("Can't stat \"%s\"", origname); ! 122: } ! 123: #if TOS ! 124: if (origfd >= 0 && (statb.st_mode & S_IJDIR)) ! 125: #else ! 126: # if OSK ! 127: if (origfd >= 0 && (statb.st_mode & S_IFDIR)) ! 128: # else ! 129: if (origfd >= 0 && (statb.st_mode & S_IFMT) != S_IFREG) ! 130: # endif ! 131: #endif ! 132: { ! 133: msg("\"%s\" is not a regular file", origname); ! 134: return tmpstart(""); ! 135: } ! 136: } ! 137: else ! 138: { ! 139: stat(".", &statb); ! 140: } ! 141: if (origfd >= 0) ! 142: { ! 143: origtime = statb.st_mtime; ! 144: #if OSK ! 145: if (*o_readonly || !(statb.st_mode & ! 146: ((getuid() >> 16) == 0 ? S_IOWRITE | S_IWRITE : ! 147: ((statb.st_gid != (getuid() >> 16) ? S_IOWRITE : S_IWRITE))))) ! 148: #endif ! 149: #if AMIGA || MSDOS ! 150: if (*o_readonly || !(statb.st_mode & S_IWRITE)) ! 151: #endif ! 152: #if TOS ! 153: # ifdef __GNUC__ ! 154: if (*o_readonly || !(statb.st_mode & S_IWRITE)) ! 155: # else ! 156: if (*o_readonly || (statb.st_mode & S_IJRON)) ! 157: # endif ! 158: #endif ! 159: #if ANY_UNIX ! 160: if (*o_readonly || !(statb.st_mode & ! 161: ((geteuid() == 0) ? 0222 : ! 162: ((statb.st_uid != geteuid() ? 0022 : 0200))))) ! 163: #endif ! 164: #if VMS ! 165: if (*o_readonly) ! 166: #endif ! 167: { ! 168: setflag(file, READONLY); ! 169: } ! 170: } ! 171: else ! 172: { ! 173: origtime = 0L; ! 174: } ! 175: } ! 176: else ! 177: { ! 178: setflag(file, NOFILE); ! 179: origfd = -1; ! 180: origtime = 0L; ! 181: stat(".", &statb); ! 182: } ! 183: ! 184: /* make a name for the tmp file */ ! 185: tmpnum++; ! 186: #if MSDOS || TOS ! 187: /* MS-Dos doesn't allow multiple slashes, but supports drives ! 188: * with current directories. ! 189: * This relies on TMPNAME beginning with "%s\\"!!!! ! 190: */ ! 191: strcpy(tmpname, o_directory); ! 192: if ((i = strlen(tmpname)) && !strchr(":/\\", tmpname[i-1])) ! 193: tmpname[i++]=SLASH; ! 194: sprintf(tmpname+i, TMPNAME+3, getpid(), tmpnum); ! 195: #else ! 196: sprintf(tmpname, TMPNAME, o_directory, getpid(), tmpnum); ! 197: #endif ! 198: ! 199: /* make sure nobody else is editing the same file */ ! 200: if (access(tmpname, 0) == 0) ! 201: { ! 202: FAIL("Temp file \"%s\" already exists?", tmpname); ! 203: } ! 204: ! 205: /* create the temp file */ ! 206: #if ANY_UNIX ! 207: close(creat(tmpname, 0600)); /* only we can read it */ ! 208: #else ! 209: close(creat(tmpname, FILEPERMS)); /* anybody body can read it, alas */ ! 210: #endif ! 211: tmpfd = open(tmpname, O_RDWR | O_BINARY); ! 212: if (tmpfd < 0) ! 213: { ! 214: FAIL("Can't create temp file... Does directory \"%s\" exist?", o_directory); ! 215: return 1; ! 216: } ! 217: ! 218: /* allocate space for the header in the file */ ! 219: write(tmpfd, hdr.c, (unsigned)BLKSIZE); ! 220: write(tmpfd, tmpblk.c, (unsigned)BLKSIZE); ! 221: ! 222: #ifndef NO_RECYCLE ! 223: /* initialize the block allocator */ ! 224: /* This must already be done here, before the first attempt ! 225: * to write to the new file! GB */ ! 226: garbage(); ! 227: #endif ! 228: ! 229: /* initialize lnum[] */ ! 230: for (i = 1; i < MAXBLKS; i++) ! 231: { ! 232: lnum[i] = INFINITY; ! 233: } ! 234: lnum[0] = 0; ! 235: ! 236: /* if there is no original file, then create a 1-line file */ ! 237: if (origfd < 0) ! 238: { ! 239: hdr.n[0] = 0; /* invalid inode# denotes new file */ ! 240: ! 241: this = blkget(1); /* get the new text block */ ! 242: strcpy(this->c, "\n"); /* put a line in it */ ! 243: ! 244: lnum[1] = 1L; /* block 1 ends with line 1 */ ! 245: nlines = 1L; /* there is 1 line in the file */ ! 246: nbytes = 1L; ! 247: ! 248: if (*origname) ! 249: { ! 250: msg("\"%s\" [NEW FILE] 1 line, 1 char", origname); ! 251: } ! 252: else ! 253: { ! 254: msg("\"[NO FILE]\" 1 line, 1 char"); ! 255: } ! 256: } ! 257: else /* there is an original file -- read it in */ ! 258: { ! 259: nbytes = nlines = 0; ! 260: ! 261: /* preallocate 1 "next" buffer */ ! 262: i = 1; ! 263: next = blkget(i); ! 264: inbuf = 0; ! 265: ! 266: /* loop, moving blocks from orig to tmp */ ! 267: for (;;) ! 268: { ! 269: /* "next" buffer becomes "this" buffer */ ! 270: this = next; ! 271: ! 272: /* read [more] text into this block */ ! 273: nread = tread(origfd, &this->c[inbuf], BLKSIZE - 1 - inbuf); ! 274: if (nread < 0) ! 275: { ! 276: close(origfd); ! 277: close(tmpfd); ! 278: tmpfd = -1; ! 279: unlink(tmpname); ! 280: FAIL("Error reading \"%s\"", origname); ! 281: } ! 282: ! 283: /* convert NUL characters to something else */ ! 284: for (j = k = inbuf; k < inbuf + nread; k++) ! 285: { ! 286: if (!this->c[k]) ! 287: { ! 288: setflag(file, HADNUL); ! 289: this->c[j++] = 0x80; ! 290: } ! 291: #ifndef CRUNCH ! 292: else if (*o_beautify && this->c[k] < ' ' && this->c[k] >= 1) ! 293: { ! 294: if (this->c[k] == '\t' ! 295: || this->c[k] == '\n' ! 296: || this->c[k] == '\f') ! 297: { ! 298: this->c[j++] = this->c[k]; ! 299: } ! 300: else if (this->c[k] == '\b') ! 301: { ! 302: /* delete '\b', but complain */ ! 303: setflag(file, HADBS); ! 304: } ! 305: /* else silently delete control char */ ! 306: } ! 307: #endif ! 308: else ! 309: { ! 310: this->c[j++] = this->c[k]; ! 311: } ! 312: } ! 313: inbuf = j; ! 314: ! 315: /* if the buffer is empty, quit */ ! 316: if (inbuf == 0) ! 317: { ! 318: goto FoundEOF; ! 319: } ! 320: ! 321: #if MSDOS || TOS ! 322: /* BAH! MS text mode read fills inbuf, then compresses eliminating \r ! 323: but leaving garbage at end of buf. The same is true for TURBOC. GB. */ ! 324: ! 325: memset(this->c + inbuf, '\0', BLKSIZE - inbuf); ! 326: #endif ! 327: ! 328: /* search backward for last newline */ ! 329: for (k = inbuf; --k >= 0 && this->c[k] != '\n';) ! 330: { ! 331: } ! 332: if (k++ < 0) ! 333: { ! 334: if (inbuf >= BLKSIZE - 1) ! 335: { ! 336: k = 80; ! 337: } ! 338: else ! 339: { ! 340: k = inbuf; ! 341: } ! 342: } ! 343: ! 344: /* allocate next buffer */ ! 345: next = blkget(++i); ! 346: ! 347: /* move fragmentary last line to next buffer */ ! 348: inbuf -= k; ! 349: for (j = 0; k < BLKSIZE; j++, k++) ! 350: { ! 351: next->c[j] = this->c[k]; ! 352: this->c[k] = 0; ! 353: } ! 354: ! 355: /* if necessary, add a newline to this buf */ ! 356: for (k = BLKSIZE - inbuf; --k >= 0 && !this->c[k]; ) ! 357: { ! 358: } ! 359: if (this->c[k] != '\n') ! 360: { ! 361: setflag(file, ADDEDNL); ! 362: this->c[k + 1] = '\n'; ! 363: } ! 364: ! 365: /* count the lines in this block */ ! 366: for (k = 0; k < BLKSIZE && this->c[k]; k++) ! 367: { ! 368: if (this->c[k] == '\n') ! 369: { ! 370: nlines++; ! 371: } ! 372: nbytes++; ! 373: } ! 374: lnum[i - 1] = nlines; ! 375: } ! 376: FoundEOF: ! 377: ! 378: /* if this is a zero-length file, add 1 line */ ! 379: if (nlines == 0) ! 380: { ! 381: this = blkget(1); /* get the new text block */ ! 382: strcpy(this->c, "\n"); /* put a line in it */ ! 383: ! 384: lnum[1] = 1; /* block 1 ends with line 1 */ ! 385: nlines = 1; /* there is 1 line in the file */ ! 386: nbytes = 1; ! 387: } ! 388: ! 389: #if MSDOS || TOS ! 390: /* each line has an extra CR that we didn't count yet */ ! 391: nbytes += nlines; ! 392: #endif ! 393: ! 394: /* report the number of lines in the file */ ! 395: msg("\"%s\" %s %ld line%s, %ld char%s", ! 396: origname, ! 397: (tstflag(file, READONLY) ? "[READONLY]" : ""), ! 398: nlines, ! 399: nlines == 1 ? "" : "s", ! 400: nbytes, ! 401: nbytes == 1 ? "" : "s"); ! 402: } ! 403: ! 404: /* initialize the cursor to start of line 1 */ ! 405: cursor = MARK_FIRST; ! 406: ! 407: /* close the original file */ ! 408: close(origfd); ! 409: ! 410: /* any other messages? */ ! 411: if (tstflag(file, HADNUL)) ! 412: { ! 413: msg("This file contained NULs. They've been changed to \\x80 chars"); ! 414: } ! 415: if (tstflag(file, ADDEDNL)) ! 416: { ! 417: msg("Newline characters have been inserted to break up long lines"); ! 418: } ! 419: #ifndef CRUNCH ! 420: if (tstflag(file, HADBS)) ! 421: { ! 422: msg("Backspace characters deleted due to ':set beautify'"); ! 423: } ! 424: #endif ! 425: ! 426: storename(origname); ! 427: ! 428: #ifndef NO_MODELINES ! 429: if (nlines > 10) ! 430: { ! 431: do_modelines(1L, 5L); ! 432: do_modelines(nlines - 4L, nlines); ! 433: } ! 434: else ! 435: { ! 436: do_modelines(1L, nlines); ! 437: } ! 438: #endif ! 439: ! 440: /* force all blocks out onto the disk, to support file recovery */ ! 441: blksync(); ! 442: ! 443: return 0; ! 444: } ! 445: ! 446: ! 447: ! 448: /* This function copies the temp file back onto an original file. ! 449: * Returns TRUE if successful, or FALSE if the file could NOT be saved. ! 450: */ ! 451: int tmpsave(filename, bang) ! 452: char *filename; /* the name to save it to */ ! 453: int bang; /* forced write? */ ! 454: { ! 455: int fd; /* fd of the file we're writing to */ ! 456: REG int len; /* length of a text block */ ! 457: REG BLK *this; /* a text block */ ! 458: long bytes; /* byte counter */ ! 459: REG int i; ! 460: ! 461: /* if no filename is given, assume the original file name */ ! 462: if (!filename || !*filename) ! 463: { ! 464: filename = origname; ! 465: } ! 466: ! 467: /* if still no file name, then fail */ ! 468: if (!*filename) ! 469: { ! 470: msg("Don't know a name for this file -- NOT WRITTEN"); ! 471: return FALSE; ! 472: } ! 473: ! 474: /* can't rewrite a READONLY file */ ! 475: if (!strcmp(filename, origname) && tstflag(file, READONLY) && !bang) ! 476: { ! 477: msg("\"%s\" [READONLY] -- NOT WRITTEN", filename); ! 478: return FALSE; ! 479: } ! 480: ! 481: /* open the file */ ! 482: if (*filename == '>' && filename[1] == '>') ! 483: { ! 484: filename += 2; ! 485: while (*filename == ' ' || *filename == '\t') ! 486: { ! 487: filename++; ! 488: } ! 489: #ifdef O_APPEND ! 490: fd = open(filename, O_WRONLY|O_APPEND); ! 491: #else ! 492: fd = open(filename, O_WRONLY); ! 493: lseek(fd, 0L, 2); ! 494: #endif ! 495: } ! 496: else ! 497: { ! 498: /* either the file must not exist, or it must be the original ! 499: * file, or we must have a bang, or "writeany" must be set. ! 500: */ ! 501: if (strcmp(filename, origname) && access(filename, 0) == 0 && !bang ! 502: #ifndef CRUNCH ! 503: && !*o_writeany ! 504: #endif ! 505: ) ! 506: { ! 507: msg("File already exists - Use :w! to overwrite"); ! 508: return FALSE; ! 509: } ! 510: #if VMS ! 511: /* Create a new VMS version of this file. */ ! 512: { ! 513: char *strrchr(), *ptr = strrchr(filename,';'); ! 514: if (ptr) *ptr = '\0'; /* Snip off any ;number in the name */ ! 515: } ! 516: #endif ! 517: fd = creat(filename, FILEPERMS); ! 518: } ! 519: if (fd < 0) ! 520: { ! 521: msg("Can't write to \"%s\" -- NOT WRITTEN", filename); ! 522: return FALSE; ! 523: } ! 524: ! 525: /* write each text block to the file */ ! 526: bytes = 0L; ! 527: for (i = 1; i < MAXBLKS && (this = blkget(i)) && this->c[0]; i++) ! 528: { ! 529: for (len = 0; len < BLKSIZE && this->c[len]; len++) ! 530: { ! 531: } ! 532: if (twrite(fd, this->c, len) < len) ! 533: { ! 534: msg("Trouble writing to \"%s\"", filename); ! 535: if (!strcmp(filename, origname)) ! 536: { ! 537: setflag(file, MODIFIED); ! 538: } ! 539: close(fd); ! 540: return FALSE; ! 541: } ! 542: bytes += len; ! 543: } ! 544: ! 545: /* reset the "modified" flag, but not the "undoable" flag */ ! 546: clrflag(file, MODIFIED); ! 547: significant = FALSE; ! 548: if (!strcmp(origname, filename)) ! 549: { ! 550: exitcode |= 1; ! 551: } ! 552: ! 553: /* report lines & characters */ ! 554: #if MSDOS || TOS ! 555: bytes += nlines; /* for the inserted carriage returns */ ! 556: #endif ! 557: msg("Wrote \"%s\" %ld lines, %ld characters", filename, nlines, bytes); ! 558: ! 559: /* close the file */ ! 560: close(fd); ! 561: ! 562: return TRUE; ! 563: } ! 564: ! 565: ! 566: /* This function deletes the temporary file. If the file has been modified ! 567: * and "bang" is FALSE, then it returns FALSE without doing anything; else ! 568: * it returns TRUE. ! 569: * ! 570: * If the "autowrite" option is set, then instead of returning FALSE when ! 571: * the file has been modified and "bang" is false, it will call tmpend(). ! 572: */ ! 573: int tmpabort(bang) ! 574: int bang; ! 575: { ! 576: /* if there is no file, return successfully */ ! 577: if (tmpfd < 0) ! 578: { ! 579: return TRUE; ! 580: } ! 581: ! 582: /* see if we must return FALSE -- can't quit */ ! 583: if (!bang && tstflag(file, MODIFIED)) ! 584: { ! 585: /* if "autowrite" is set, then act like tmpend() */ ! 586: if (*o_autowrite) ! 587: return tmpend(bang); ! 588: else ! 589: return FALSE; ! 590: } ! 591: ! 592: /* delete the tmp file */ ! 593: cutswitch(); ! 594: strcpy(prevorig, origname); ! 595: prevline = markline(cursor); ! 596: *origname = '\0'; ! 597: origtime = 0L; ! 598: blkinit(); ! 599: nlines = 0; ! 600: initflags(); ! 601: return TRUE; ! 602: } ! 603: ! 604: /* This function saves the file if it has been modified, and then deletes ! 605: * the temporary file. Returns TRUE if successful, or FALSE if the file ! 606: * needs to be saved but can't be. When it returns FALSE, it will not have ! 607: * deleted the tmp file, either. ! 608: */ ! 609: int tmpend(bang) ! 610: int bang; ! 611: { ! 612: /* save the file if it has been modified */ ! 613: if (tstflag(file, MODIFIED) && !tmpsave((char *)0, FALSE) && !bang) ! 614: { ! 615: return FALSE; ! 616: } ! 617: ! 618: /* delete the tmp file */ ! 619: tmpabort(TRUE); ! 620: ! 621: return TRUE; ! 622: } ! 623: ! 624: ! 625: /* If the tmp file has been changed, then this function will force those ! 626: * changes to be written to the disk, so that the tmp file will survive a ! 627: * system crash or power failure. ! 628: */ ! 629: #if AMIGA || MSDOS || TOS ! 630: sync() ! 631: { ! 632: /* MS-DOS and TOS don't flush their buffers until the file is closed, ! 633: * so here we close the tmp file and then immediately reopen it. ! 634: */ ! 635: close(tmpfd); ! 636: tmpfd = open(tmpname, O_RDWR | O_BINARY); ! 637: return 0; ! 638: } ! 639: #endif ! 640: ! 641: ! 642: /* This function stores the file's name in the second block of the temp file. ! 643: * SLEAZE ALERT! SLEAZE ALERT! The "tmpblk" buffer is probably being used ! 644: * to store the arguments to a command, so we can't use it here. Instead, ! 645: * we'll borrow the buffer that is used for "shift-U". ! 646: */ ! 647: int ! 648: storename(name) ! 649: char *name; /* the name of the file - normally origname */ ! 650: { ! 651: #ifndef CRUNCH ! 652: int len; ! 653: char *ptr; ! 654: #endif ! 655: ! 656: /* we're going to clobber the U_text buffer, so reset U_line */ ! 657: U_line = 0L; ! 658: ! 659: if (!name) ! 660: { ! 661: strncpy(U_text, "", BLKSIZE); ! 662: U_text[1] = 127; ! 663: } ! 664: #ifndef CRUNCH ! 665: else if (*name != SLASH) ! 666: { ! 667: /* get the directory name */ ! 668: ptr = getcwd(U_text, BLKSIZE); ! 669: if (ptr != U_text) ! 670: { ! 671: strcpy(U_text, ptr); ! 672: } ! 673: ! 674: /* append a slash to the directory name */ ! 675: len = strlen(U_text); ! 676: U_text[len++] = SLASH; ! 677: ! 678: /* append the filename, padded with heaps o' NULs */ ! 679: strncpy(U_text + len, *name ? name : "foo", BLKSIZE - len); ! 680: } ! 681: #endif ! 682: else ! 683: { ! 684: /* copy the filename into U_text */ ! 685: strncpy(U_text, *name ? name : "foo", BLKSIZE); ! 686: } ! 687: ! 688: if (tmpfd >= 0) ! 689: { ! 690: /* write the name out to second block of the temp file */ ! 691: lseek(tmpfd, (long)BLKSIZE, 0); ! 692: write(tmpfd, U_text, (unsigned)BLKSIZE); ! 693: } ! 694: return 0; ! 695: } ! 696: ! 697: ! 698: ! 699: /* This function handles deadly signals. It restores sanity to the terminal ! 700: * preserves the current temp file, and deletes any old temp files. ! 701: */ ! 702: int deathtrap(sig) ! 703: int sig; /* the deadly signal that we caught */ ! 704: { ! 705: char *why; ! 706: ! 707: /* restore the terminal's sanity */ ! 708: endwin(); ! 709: ! 710: #ifdef CRUNCH ! 711: why = "-Elvis died"; ! 712: #else ! 713: /* give a more specific description of how Elvis died */ ! 714: switch (sig) ! 715: { ! 716: # ifdef SIGHUP ! 717: case SIGHUP: why = "-the modem lost its carrier"; break; ! 718: # endif ! 719: # ifndef DEBUG ! 720: # ifdef SIGILL ! 721: case SIGILL: why = "-Elvis hit an illegal instruction"; break; ! 722: # endif ! 723: # ifdef SIGBUS ! 724: case SIGBUS: why = "-Elvis had a bus error"; break; ! 725: # endif ! 726: # ifdef SIGSEGV ! 727: # if !TOS ! 728: case SIGSEGV: why = "-Elvis had a segmentation violation"; break; ! 729: # endif ! 730: # endif ! 731: # ifdef SIGSYS ! 732: case SIGSYS: why = "-Elvis munged a system call"; break; ! 733: # endif ! 734: # endif /* !DEBUG */ ! 735: # ifdef SIGPIPE ! 736: case SIGPIPE: why = "-the pipe reader died"; break; ! 737: # endif ! 738: # ifdef SIGTERM ! 739: case SIGTERM: why = "-Elvis was terminated"; break; ! 740: # endif ! 741: # if !MINIX ! 742: # ifdef SIGUSR1 ! 743: case SIGUSR1: why = "-Elvis was killed via SIGUSR1"; break; ! 744: # endif ! 745: # ifdef SIGUSR2 ! 746: case SIGUSR2: why = "-Elvis was killed via SIGUSR2"; break; ! 747: # endif ! 748: # endif ! 749: default: why = "-Elvis died"; break; ! 750: } ! 751: #endif ! 752: ! 753: /* if we had a temp file going, then preserve it */ ! 754: if (tmpnum > 0 && tmpfd >= 0) ! 755: { ! 756: close(tmpfd); ! 757: sprintf(tmpblk.c, "%s \"%s\" %s", PRESERVE, why, tmpname); ! 758: system(tmpblk.c); ! 759: } ! 760: ! 761: /* delete any old temp files */ ! 762: cutend(); ! 763: ! 764: /* exit with the proper exit status */ ! 765: exit(sig); ! 766: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.