home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 365_02 / tmp.c < prev    next >
C/C++ Source or Header  |  1992-04-06  |  17KB  |  760 lines

  1. /* tmp.c */
  2.  
  3. /* Author:
  4.  *    Steve Kirkendall
  5.  *    14407 SW Teal Blvd. #C
  6.  *    Beaverton, OR 97005
  7.  *    kirkenda@cs.pdx.edu
  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 || (TOS && defined(__GNUC__))
  150.             if (*o_readonly || !(statb.st_mode & S_IWRITE))
  151. #endif
  152. #if TOS && !defined(__GNUC__)
  153.             if (*o_readonly || (statb.st_mode & S_IJRON))
  154. #endif
  155. #if ANY_UNIX
  156.             if (*o_readonly || !(statb.st_mode &
  157.                   ((geteuid() == 0) ? 0222 :
  158.                   ((statb.st_uid != geteuid() ? 0022 : 0200)))))
  159. #endif
  160. #if VMS
  161.             if (*o_readonly)
  162. #endif
  163.             {
  164.                 setflag(file, READONLY);
  165.             }
  166.         }
  167.         else
  168.         {
  169.             origtime = 0L;
  170.         }
  171.     }
  172.     else
  173.     {
  174.         setflag(file, NOFILE);
  175.         origfd = -1;
  176.         origtime = 0L;
  177.         stat(".", &statb);
  178.     }
  179.  
  180.     /* make a name for the tmp file */
  181.     tmpnum++;
  182. #if MSDOS || TOS
  183.     /* MS-Dos doesn't allow multiple slashes, but supports drives
  184.      * with current directories.
  185.      * This relies on TMPNAME beginning with "%s\\"!!!!
  186.      */
  187.     strcpy(tmpname, o_directory);
  188.     if ((i = strlen(tmpname)) && !strchr(":/\\", tmpname[i-1]))
  189.         tmpname[i++]=SLASH;
  190.     sprintf(tmpname+i, TMPNAME+3, getpid(), tmpnum);
  191. #else
  192.     sprintf(tmpname, TMPNAME, o_directory, getpid(), tmpnum);
  193. #endif
  194.  
  195.     /* make sure nobody else is editing the same file */
  196.     if (access(tmpname, 0) == 0)
  197.     {
  198.         FAIL("Temp file \"%s\" already exists?", tmpname);
  199.     }
  200.  
  201.     /* create the temp file */
  202. #if ANY_UNIX
  203.     close(creat(tmpname, 0600));        /* only we can read it */
  204. #else
  205.     close(creat(tmpname, FILEPERMS));    /* anybody body can read it, alas */
  206. #endif
  207.     tmpfd = open(tmpname, O_RDWR | O_BINARY);
  208.     if (tmpfd < 0)
  209.     {
  210.         FAIL("Can't create temp file... Does directory \"%s\" exist?", o_directory);
  211.         return 1;
  212.     }
  213.  
  214.     /* allocate space for the header in the file */
  215.     write(tmpfd, hdr.c, (unsigned)BLKSIZE);
  216.     write(tmpfd, tmpblk.c, (unsigned)BLKSIZE);
  217.  
  218. #ifndef NO_RECYCLE
  219.     /* initialize the block allocator */
  220.     /* This must already be done here, before the first attempt
  221.      * to write to the new file! GB */
  222.     garbage();
  223. #endif
  224.  
  225.     /* initialize lnum[] */
  226.     for (i = 1; i < MAXBLKS; i++)
  227.     {
  228.         lnum[i] = INFINITY;
  229.     }
  230.     lnum[0] = 0;
  231.  
  232.     /* if there is no original file, then create a 1-line file */
  233.     if (origfd < 0)
  234.     {
  235.         hdr.n[0] = 0;    /* invalid inode# denotes new file */
  236.  
  237.         this = blkget(1);     /* get the new text block */
  238.         strcpy(this->c, "\n");    /* put a line in it */
  239.  
  240.         lnum[1] = 1L;    /* block 1 ends with line 1 */
  241.         nlines = 1L;    /* there is 1 line in the file */
  242.         nbytes = 1L;
  243.  
  244.         if (*origname)
  245.         {
  246.             msg("\"%s\" [NEW FILE]  1 line, 1 char", origname);
  247.         }
  248.         else
  249.         {
  250.             msg("\"[NO FILE]\"  1 line, 1 char");
  251.         }
  252.     }
  253.     else /* there is an original file -- read it in */
  254.     {
  255.         nbytes = nlines = 0;
  256.  
  257.         /* preallocate 1 "next" buffer */
  258.         i = 1;
  259.         next = blkget(i);
  260.         inbuf = 0;
  261.  
  262.         /* loop, moving blocks from orig to tmp */
  263.         for (;;)
  264.         {
  265.             /* "next" buffer becomes "this" buffer */
  266.             this = next;
  267.  
  268.             /* read [more] text into this block */
  269.             nread = tread(origfd, &this->c[inbuf], BLKSIZE - 1 - inbuf);
  270.             if (nread < 0)
  271.             {
  272.                 close(origfd);
  273.                 close(tmpfd);
  274.                 tmpfd = -1;
  275.                 unlink(tmpname);
  276.                 FAIL("Error reading \"%s\"", origname);
  277.             }
  278.  
  279.             /* convert NUL characters to something else */
  280.             for (j = k = inbuf; k < inbuf + nread; k++)
  281.             {
  282.                 if (!this->c[k])
  283.                 {
  284.                     setflag(file, HADNUL);
  285.                     this->c[j++] = 0x80;
  286.                 }
  287. #ifndef CRUNCH
  288.                 else if (*o_beautify && this->c[k] < ' ' && this->c[k] > 0)
  289.                 {
  290.                     if (this->c[k] == '\t'
  291.                      || this->c[k] == '\n'
  292.                      || this->c[k] == '\f')
  293.                     {
  294.                         this->c[j++] = this->c[k];
  295.                     }
  296.                     else if (this->c[k] == '\b')
  297.                     {
  298.                         /* delete '\b', but complain */
  299.                         setflag(file, HADBS);
  300.                     }
  301.                     /* else silently delete control char */
  302.                 }
  303. #endif
  304.                 else
  305.                 {
  306.                     this->c[j++] = this->c[k];
  307.                 }
  308.             }
  309.             inbuf = j;
  310.  
  311.             /* if the buffer is empty, quit */
  312.             if (inbuf == 0)
  313.             {
  314.                 goto FoundEOF;
  315.             }
  316.  
  317. #if MSDOS || TOS
  318. /* BAH! MS text mode read fills inbuf, then compresses eliminating \r
  319.    but leaving garbage at end of buf. The same is true for TURBOC. GB. */
  320.  
  321.             memset(this->c + inbuf, '\0', BLKSIZE - inbuf);
  322. #endif
  323.  
  324.             /* search backward for last newline */
  325.             for (k = inbuf; --k >= 0 && this->c[k] != '\n';)
  326.             {
  327.             }
  328.             if (k++ < 0)
  329.             {
  330.                 if (inbuf >= BLKSIZE - 1)
  331.                 {
  332.                     k = 80;
  333.                 }
  334.                 else
  335.                 {
  336.                     k = inbuf;
  337.                 }
  338.             }
  339.  
  340.             /* allocate next buffer */
  341.             next = blkget(++i);
  342.  
  343.             /* move fragmentary last line to next buffer */
  344.             inbuf -= k;
  345.             for (j = 0; k < BLKSIZE; j++, k++)
  346.             {
  347.                 next->c[j] = this->c[k];
  348.                 this->c[k] = 0;
  349.             }
  350.  
  351.             /* if necessary, add a newline to this buf */
  352.             for (k = BLKSIZE - inbuf; --k >= 0 && !this->c[k]; )
  353.             {
  354.             }
  355.             if (this->c[k] != '\n')
  356.             {
  357.                 setflag(file, ADDEDNL);
  358.                 this->c[k + 1] = '\n';
  359.             }
  360.  
  361.             /* count the lines in this block */
  362.             for (k = 0; k < BLKSIZE && this->c[k]; k++)
  363.             {
  364.                 if (this->c[k] == '\n')
  365.                 {
  366.                     nlines++;
  367.                 }
  368.                 nbytes++;
  369.             }
  370.             lnum[i - 1] = nlines;
  371.         }
  372. FoundEOF:
  373.  
  374.         /* if this is a zero-length file, add 1 line */
  375.         if (nlines == 0)
  376.         {
  377.             this = blkget(1);     /* get the new text block */
  378.             strcpy(this->c, "\n");    /* put a line in it */
  379.  
  380.             lnum[1] = 1;    /* block 1 ends with line 1 */
  381.             nlines = 1;    /* there is 1 line in the file */
  382.             nbytes = 1;
  383.         }
  384.  
  385. #if MSDOS || TOS
  386.         /* each line has an extra CR that we didn't count yet */
  387.         nbytes += nlines;
  388. #endif
  389.  
  390.         /* report the number of lines in the file */
  391.         msg("\"%s\" %s %ld line%s, %ld char%s",
  392.             origname,
  393.             (tstflag(file, READONLY) ? "[READONLY]" : ""),
  394.             nlines,
  395.             nlines == 1 ? "" : "s",
  396.             nbytes,
  397.             nbytes == 1 ? "" : "s");
  398.     }
  399.  
  400.     /* initialize the cursor to start of line 1 */
  401.     cursor = MARK_FIRST;
  402.  
  403.     /* close the original file */
  404.     close(origfd);
  405.  
  406.     /* any other messages? */
  407.     if (tstflag(file, HADNUL))
  408.     {
  409.         msg("This file contained NULs.  They've been changed to \\x80 chars");
  410.     }
  411.     if (tstflag(file, ADDEDNL))
  412.     {
  413.         msg("Newline characters have been inserted to break up long lines");
  414.     }
  415. #ifndef CRUNCH
  416.     if (tstflag(file, HADBS))
  417.     {
  418.         msg("Backspace characters deleted due to ':set beautify'");
  419.     }
  420. #endif
  421.  
  422.     storename(origname);
  423.  
  424. #ifndef NO_MODELINES
  425.     if (nlines > 10)
  426.     {
  427.         do_modelines(1L, 5L);
  428.         do_modelines(nlines - 4L, nlines);
  429.     }
  430.     else
  431.     {
  432.         do_modelines(1L, nlines);
  433.     }
  434. #endif
  435.  
  436.     /* force all blocks out onto the disk, to support file recovery */
  437.     blksync();
  438.  
  439.     return 0;
  440. }
  441.  
  442.  
  443.  
  444. /* This function copies the temp file back onto an original file.
  445.  * Returns TRUE if successful, or FALSE if the file could NOT be saved.
  446.  */
  447. int tmpsave(filename, bang)
  448.     char    *filename;    /* the name to save it to */
  449.     int    bang;        /* forced write? */
  450. {
  451.     int        fd;    /* fd of the file we're writing to */
  452.     REG int        len;    /* length of a text block */
  453.     REG BLK        *this;    /* a text block */
  454.     long        bytes;    /* byte counter */
  455.     REG int        i;
  456.  
  457.     /* if no filename is given, assume the original file name */
  458.     if (!filename || !*filename)
  459.     {
  460.         filename = origname;
  461.     }
  462.  
  463.     /* if still no file name, then fail */
  464.     if (!*filename)
  465.     {
  466.         msg("Don't know a name for this file -- NOT WRITTEN");
  467.         return FALSE;
  468.     }
  469.  
  470.     /* can't rewrite a READONLY file */
  471. #if AMIGA
  472.     if (!strcmp(filename, origname) && tstflag(file, READONLY) && !bang)
  473. #else
  474.     if (!strcmp(filename, origname) && *o_readonly && !bang)
  475. #endif
  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.  
  549.     /* report lines & characters */
  550. #if MSDOS || TOS
  551.     bytes += nlines; /* for the inserted carriage returns */
  552. #endif
  553.     msg("Wrote \"%s\"  %ld lines, %ld characters", filename, nlines, bytes);
  554.  
  555.     /* close the file */
  556.     close(fd);
  557.  
  558.     return TRUE;
  559. }
  560.  
  561.  
  562. /* This function deletes the temporary file.  If the file has been modified
  563.  * and "bang" is FALSE, then it returns FALSE without doing anything; else
  564.  * it returns TRUE.
  565.  *
  566.  * If the "autowrite" option is set, then instead of returning FALSE when
  567.  * the file has been modified and "bang" is false, it will call tmpend().
  568.  */
  569. int tmpabort(bang)
  570.     int    bang;
  571. {
  572.     /* if there is no file, return successfully */
  573.     if (tmpfd < 0)
  574.     {
  575.         return TRUE;
  576.     }
  577.  
  578.     /* see if we must return FALSE -- can't quit */
  579.     if (!bang && tstflag(file, MODIFIED))
  580.     {
  581.         /* if "autowrite" is set, then act like tmpend() */
  582.         if (*o_autowrite)
  583.             return tmpend(bang);
  584.         else
  585.             return FALSE;
  586.     }
  587.  
  588.     /* delete the tmp file */
  589.     cutswitch();
  590.     strcpy(prevorig, origname);
  591.     prevline = markline(cursor);
  592.     *origname = '\0';
  593.     origtime = 0L;
  594.     blkinit();
  595.     nlines = 0;
  596.     initflags();
  597.     return TRUE;
  598. }
  599.  
  600. /* This function saves the file if it has been modified, and then deletes
  601.  * the temporary file. Returns TRUE if successful, or FALSE if the file
  602.  * needs to be saved but can't be.  When it returns FALSE, it will not have
  603.  * deleted the tmp file, either.
  604.  */
  605. int tmpend(bang)
  606.     int    bang;
  607. {
  608.     /* save the file if it has been modified */
  609.     if (tstflag(file, MODIFIED) && !tmpsave((char *)0, FALSE) && !bang)
  610.     {
  611.         return FALSE;
  612.     }
  613.  
  614.     /* delete the tmp file */
  615.     tmpabort(TRUE);
  616.  
  617.     return TRUE;
  618. }
  619.  
  620.  
  621. /* If the tmp file has been changed, then this function will force those
  622.  * changes to be written to the disk, so that the tmp file will survive a
  623.  * system crash or power failure.
  624.  */
  625. #if AMIGA || MSDOS || TOS
  626. sync()
  627. {
  628.     /* MS-DOS and TOS don't flush their buffers until the file is closed,
  629.      * so here we close the tmp file and then immediately reopen it.
  630.      */
  631.     close(tmpfd);
  632.     tmpfd = open(tmpname, O_RDWR | O_BINARY);
  633.     return 0;
  634. }
  635. #endif
  636.  
  637.  
  638. /* This function stores the file's name in the second block of the temp file.
  639.  * SLEAZE ALERT!  SLEAZE ALERT!  The "tmpblk" buffer is probably being used
  640.  * to store the arguments to a command, so we can't use it here.  Instead,
  641.  * we'll borrow the buffer that is used for "shift-U".
  642.  */
  643. storename(name)
  644.     char    *name;    /* the name of the file - normally origname */
  645. {
  646. #ifndef CRUNCH
  647.     int    len;
  648.     char    *ptr;
  649. #endif
  650.  
  651.     /* we're going to clobber the U_text buffer, so reset U_line */
  652.     U_line = 0L;
  653.  
  654.     if (!name)
  655.     {
  656.         strncpy(U_text, "", BLKSIZE);
  657.         U_text[1] = 127;
  658.     }
  659. #ifndef CRUNCH
  660.     else if (*name != SLASH)
  661.     {
  662.         /* get the directory name */
  663.         ptr = getcwd(U_text, BLKSIZE);
  664.         if (ptr != U_text)
  665.         {
  666.             strcpy(U_text, ptr);
  667.         }
  668.  
  669.         /* append a slash to the directory name */
  670.         len = strlen(U_text);
  671.         U_text[len++] = SLASH;
  672.  
  673.         /* append the filename, padded with heaps o' NULs */
  674.         strncpy(U_text + len, *name ? name : "foo", BLKSIZE - len);
  675.     }
  676. #endif
  677.     else
  678.     {
  679.         /* copy the filename into U_text */
  680.         strncpy(U_text, *name ? name : "foo", BLKSIZE);
  681.     }
  682.  
  683.     if (tmpfd >= 0)
  684.     {
  685.         /* write the name out to second block of the temp file */
  686.         lseek(tmpfd, (long)BLKSIZE, 0);
  687.         write(tmpfd, U_text, (unsigned)BLKSIZE);
  688.     }
  689.     return 0;
  690. }
  691.  
  692.  
  693.  
  694. /* This function handles deadly signals.  It restores sanity to the terminal
  695.  * preserves the current temp file, and deletes any old temp files.
  696.  */
  697. int deathtrap(sig)
  698.     int    sig;    /* the deadly signal that we caught */
  699. {
  700.     char    *why;
  701.  
  702.     /* restore the terminal's sanity */
  703.     endwin();
  704.  
  705. #ifdef CRUNCH
  706.     why = "-Elvis died";
  707. #else
  708.     /* give a more specific description of how Elvis died */
  709.     switch (sig)
  710.     {
  711. # ifdef SIGHUP
  712.       case SIGHUP:    why = "-the modem lost its carrier";        break;
  713. # endif
  714. # ifndef DEBUG
  715. #  ifdef SIGILL
  716.       case SIGILL:    why = "-Elvis hit an illegal instruction";    break;
  717. #  endif
  718. #  ifdef SIGBUS
  719.       case SIGBUS:    why = "-Elvis had a bus error";            break;
  720. #  endif
  721. #  if defined(SIGSEGV) && !defined(TOS)
  722.       case SIGSEGV:    why = "-Elvis had a segmentation violation";    break;
  723. #  endif
  724. #  ifdef SIGSYS
  725.       case SIGSYS:    why = "-Elvis munged a system call";        break;
  726. #  endif
  727. # endif /* !DEBUG */
  728. # ifdef SIGPIPE
  729.       case SIGPIPE:    why = "-the pipe reader died";            break;
  730. # endif
  731. # ifdef SIGTERM
  732.       case SIGTERM:    why = "-Elvis was terminated";            break;
  733. # endif
  734. # if !MINIX
  735. #  ifdef SIGUSR1
  736.       case SIGUSR1:    why = "-Elvis was killed via SIGUSR1";        break;
  737. #  endif
  738. #  ifdef SIGUSR2
  739.       case SIGUSR2:    why = "-Elvis was killed via SIGUSR2";        break;
  740. #  endif
  741. # endif
  742.       default:    why = "-Elvis died";                break;
  743.     }
  744. #endif
  745.  
  746.     /* if we had a temp file going, then preserve it */
  747.     if (tmpnum > 0 && tmpfd >= 0)
  748.     {
  749.         close(tmpfd);
  750.         sprintf(tmpblk.c, "%s \"%s\" %s", PRESERVE, why, tmpname);
  751.         system(tmpblk.c);
  752.     }
  753.  
  754.     /* delete any old temp files */
  755.     cutend();
  756.  
  757.     /* exit with the proper exit status */
  758.     exit(sig);
  759. }
  760.