home *** CD-ROM | disk | FTP | other *** search
- /* status.c: functions for printing fancy status messages in rc */
-
- #include "rc.h"
- #include "sigmsgs.h"
-
- /* status == the wait() value of the last command in the pipeline, or the last command */
-
- static int statuses[512];
- static int pipelength = 1;
-
- /*
- Test to see if rc's status is true. According to td, status is true
- if and only if every pipe-member has an exit status of zero.
- */
-
- extern int istrue() {
- int i;
- for (i = 0; i < pipelength; i++)
- if (statuses[i] != 0)
- return FALSE;
- return TRUE;
- }
-
- /*
- Return the status as an integer. A status which has low-bits set is
- a signal number, whereas a status with high bits set is a value set
- from exit(). The presence of a signal just sets status to 1. Also,
- a pipeline with nonzero exit statuses in it just sets status to 1.
- */
-
- extern int getstatus() {
- int s;
- if (pipelength > 1)
- return !istrue();
- s = statuses[0];
- return (s&0xff) ? 1 : (s >> 8) & 0xff;
- }
-
- extern void set(bool code) {
- setstatus(-1, (!code) << 8); /* exit status 1 == 0x100 */
- }
-
- /* take a pipeline and store the exit statuses. Check to see whether any of the children dumped core */
-
- extern void setpipestatus(int stats[], int num) {
- int i;
- for (i = 0; i < (pipelength = num); i++) {
- statprint(-1, stats[i]);
- statuses[i] = stats[i];
- }
- }
-
- /* set a simple status, as opposed to a pipeline */
-
- extern void setstatus(int pid, int i) {
- pipelength = 1;
- statuses[0] = i;
- statprint(pid, i);
- }
-
- /* print a message if termination was with a signal, and if the child dumped core. exit on error if -e is set */
-
- extern void statprint(int pid, int i) {
- if (i & 0xff) {
- char *msg = ((i & 0x7f) < NUMOFSIGNALS ? signals[i & 0x7f].msg : "");
- if (pid != -1)
- fprint(2, "%d: ", pid);
- if (i & 0x80) {
- if (*msg == '\0')
- fprint(2, "core dumped\n");
- else
- fprint(2, "%s--core dumped\n", msg);
- } else if (*msg != '\0')
- fprint(2, "%s\n", msg);
- }
- if (i != 0 && dashee && !cond)
- rc_exit(getstatus());
- }
-
- /* prepare a list to be passed back. Used whenever $status is dereferenced */
-
- extern List *sgetstatus() {
- List *r;
- int i;
- for (r = NULL, i = 0; i < pipelength; i++) {
- List *q = nnew(List);
- int s = statuses[i];
- int t;
- q->n = r;
- r = q;
- if ((t = s & 0x7f) != 0) {
- const char *core = (s & 0x80) ? "+core" : "";
- if (t < NUMOFSIGNALS && *signals[t].name != '\0')
- r->w = nprint("%s%s", signals[t].name, core);
- else
- r->w = nprint("-%d%s", t, core); /* unknown signals are negated */
- } else
- r->w = nprint("%d", (s >> 8) & 0xff);
- r->m = NULL;
- }
- return r;
- }
-
- extern void ssetstatus(char **av) {
- int i, j, k, l;
- bool found;
- for (l = 0; av[l] != NULL; l++)
- ; /* count up array length */
- --l;
- for (i = 0; av[i] != NULL; i++) {
- j = a2u(av[i]);
- if (j >= 0) {
- statuses[l - i] = j << 8;
- continue;
- }
- found = FALSE;
- for (k = 0; k < NUMOFSIGNALS; k++) {
- if (streq(signals[k].name, av[i])) {
- statuses[l - i] = k;
- found = TRUE;
- break;
- }
- else {
- SIZE_T len = strlen(signals[k].name);
- if (strncmp(signals[k].name, av[i], len) == 0 && streq(av[i] + len, "+core")) {
- statuses[l - i] = k + 0x80;
- found = TRUE;
- break;
- }
- }
- }
- if (!found) {
- fprint(2, "bad status\n");
- set(FALSE);
- return;
- }
- }
- pipelength = i;
- }
-