home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume30 / rc / part06 / status.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-30  |  3.2 KB  |  140 lines

  1. /* status.c: functions for printing fancy status messages in rc */
  2.  
  3. #include "rc.h"
  4. #include "sigmsgs.h"
  5.  
  6. /* status == the wait() value of the last command in the pipeline, or the last command */
  7.  
  8. static int statuses[512];
  9. static int pipelength = 1;
  10.  
  11. /*
  12.    Test to see if rc's status is true. According to td, status is true
  13.    if and only if every pipe-member has an exit status of zero.
  14. */
  15.  
  16. extern int istrue() {
  17.     int i;
  18.     for (i = 0; i < pipelength; i++)
  19.         if (statuses[i] != 0)
  20.             return FALSE;
  21.     return TRUE;
  22. }
  23.  
  24. /*
  25.    Return the status as an integer. A status which has low-bits set is
  26.    a signal number, whereas a status with high bits set is a value set
  27.    from exit(). The presence of a signal just sets status to 1. Also,
  28.    a pipeline with nonzero exit statuses in it just sets status to 1.
  29. */
  30.  
  31. extern int getstatus() {
  32.     int s;
  33.     if (pipelength > 1)
  34.         return !istrue();
  35.     s = statuses[0];
  36.     return (s&0xff) ? 1 : (s >> 8) & 0xff;
  37. }
  38.  
  39. extern void set(bool code) {
  40.     setstatus(-1, (!code) << 8); /* exit status 1 == 0x100 */
  41. }
  42.  
  43. /* take a pipeline and store the exit statuses. Check to see whether any of the children dumped core */
  44.  
  45. extern void setpipestatus(int stats[], int num) {
  46.     int i;
  47.     for (i = 0; i < (pipelength = num); i++) {
  48.         statprint(-1, stats[i]);
  49.         statuses[i] = stats[i];
  50.     }
  51. }
  52.  
  53. /* set a simple status, as opposed to a pipeline */
  54.  
  55. extern void setstatus(int pid, int i) {
  56.     pipelength = 1;
  57.     statuses[0] = i;
  58.     statprint(pid, i);
  59. }
  60.  
  61. /* print a message if termination was with a signal, and if the child dumped core. exit on error if -e is set */
  62.  
  63. extern void statprint(int pid, int i) {
  64.     if (i & 0xff) {
  65.         char *msg = ((i & 0x7f) < NUMOFSIGNALS ? signals[i & 0x7f].msg : "");
  66.         if (pid != -1)
  67.             fprint(2, "%d: ", pid);
  68.         if (i & 0x80) {
  69.             if (*msg == '\0')
  70.                 fprint(2, "core dumped\n");
  71.             else
  72.                 fprint(2, "%s--core dumped\n", msg);
  73.         } else if (*msg != '\0')
  74.             fprint(2, "%s\n", msg);
  75.     }
  76.     if (i != 0 && dashee && !cond)
  77.         rc_exit(getstatus());
  78. }
  79.  
  80. /* prepare a list to be passed back. Used whenever $status is dereferenced */
  81.  
  82. extern List *sgetstatus() {
  83.     List *r;
  84.     int i;
  85.     for (r = NULL, i = 0; i < pipelength; i++) {
  86.         List *q = nnew(List);
  87.         int s = statuses[i];
  88.         int t;
  89.         q->n = r;
  90.         r = q;
  91.         if ((t = s & 0x7f) != 0) {
  92.             const char *core = (s & 0x80) ? "+core" : "";
  93.             if (t < NUMOFSIGNALS && *signals[t].name != '\0')
  94.                 r->w = nprint("%s%s", signals[t].name, core);
  95.             else
  96.                 r->w = nprint("-%d%s", t, core); /* unknown signals are negated */
  97.         } else
  98.             r->w = nprint("%d", (s >> 8) & 0xff);
  99.         r->m = NULL;
  100.     }
  101.     return r;
  102. }
  103.  
  104. extern void ssetstatus(char **av) {
  105.     int i, j, k, l;
  106.     bool found;
  107.     for (l = 0; av[l] != NULL; l++)
  108.         ; /* count up array length */
  109.     --l;
  110.     for (i = 0; av[i] != NULL; i++) {
  111.         j = a2u(av[i]);
  112.         if (j >= 0) {
  113.             statuses[l - i] = j << 8;
  114.             continue;
  115.         }
  116.         found = FALSE;
  117.         for (k = 0; k < NUMOFSIGNALS; k++) {
  118.             if (streq(signals[k].name, av[i])) {
  119.                 statuses[l - i] = k;
  120.                 found = TRUE;
  121.                 break;
  122.             } 
  123.             else {
  124.                 SIZE_T len = strlen(signals[k].name);
  125.                 if (strncmp(signals[k].name, av[i], len) == 0 && streq(av[i] + len, "+core")) {
  126.                     statuses[l - i] = k + 0x80;
  127.                     found = TRUE;
  128.                     break;
  129.                 }
  130.             }
  131.         }
  132.         if (!found) {
  133.             fprint(2, "bad status\n");
  134.             set(FALSE);
  135.             return;
  136.         }
  137.     }
  138.     pipelength = i;
  139. }
  140.