summaryrefslogtreecommitdiff
path: root/fn.c
diff options
context:
space:
mode:
authortim <tim>1997-05-14 15:30:41 +0000
committerToby Goodwin <toby@paccrat.org>2015-05-16 21:23:00 +0100
commit53cf1b1c1c3f0c2b5067afccc2976b99a574a089 (patch)
treea31f167c3779362e29ab377d662052b6257253a8 /fn.c
parentb87bfedf65c289bf0ee5338c9e10492b70b1e8e0 (diff)
Initial revision
Diffstat (limited to 'fn.c')
-rw-r--r--fn.c257
1 files changed, 0 insertions, 257 deletions
diff --git a/fn.c b/fn.c
deleted file mode 100644
index 053ed89..0000000
--- a/fn.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- fn.c: functions for adding and deleting functions from the symbol table.
- Support for signal handlers is also found here.
-*/
-
-#include <signal.h>
-#include <errno.h>
-#include "rc.h"
-#include "sigmsgs.h"
-
-static void fn_handler(int), dud_handler(int);
-
-static bool runexit = FALSE;
-static Node *handlers[NUMOFSIGNALS], null;
-static void (*def_sigint)(int) = SIG_DFL;
-static void (*def_sigquit)(int) = SIG_DFL;
-static void (*def_sigterm)(int) = SIG_DFL;
-
-/*
- Set signals to default values for rc. This means that interactive
- shells ignore SIGTERM, etc.
-*/
-
-extern void inithandler() {
- int i;
- null.type = nBody;
- null.u[0].p = null.u[1].p = NULL;
- for (i = 1; i < NUMOFSIGNALS; i++)
-#ifndef HAVE_RESTARTABLE_SYSCALLS
- if (i != SIGCLD)
-#endif
- if (sighandlers[i] == SIG_IGN)
- fnassign(signals[i].name, NULL); /* ignore incoming ignored signals */
- if (interactive || sighandlers[SIGINT] != SIG_IGN) {
- def_sigint = sigint;
- fnrm("sigint"); /* installs SIGINT catcher if not inherited ignored */
- }
- if (!dashdee) {
- if (interactive || sighandlers[SIGQUIT] != SIG_IGN) {
- def_sigquit = dud_handler;
- fnrm("sigquit"); /* "ignores" SIGQUIT unless inherited ignored */
- }
- if (interactive) {
- def_sigterm = dud_handler;
- fnrm("sigterm"); /* ditto for SIGTERM */
- }
- }
-}
-
-/* only run this in a child process! resets signals to their default values */
-
-extern void setsigdefaults(bool sysvbackground) {
- int i;
- /*
- General housekeeping: setsigdefaults happens after fork(),
- so it's a convenient place to clean up open file descriptors.
- (history file, scripts, etc.)
- */
- closefds();
- /*
- Restore signals to SIG_DFL, paying close attention to
- a few quirks: SIGINT, SIGQUIT and are treated specially
- depending on whether we are doing v7-style backgrounding
- or not; the default action for SIGINT, SIGQUIT and SIGTERM
- must be set to the appropriate action; finally, care must
- be taken not to set to SIG_DFL any signals which are being
- ignored.
- */
- for (i = 1; i < NUMOFSIGNALS; i++)
- if (sighandlers[i] != SIG_IGN) {
- handlers[i] = NULL;
- switch (i) {
- case SIGINT:
- if (sysvbackground) {
- def_sigint = SIG_IGN;
- fnassign("sigint", NULL); /* ignore */
- } else {
- def_sigint = SIG_DFL;
- goto sigcommon;
- }
- break;
- case SIGQUIT:
- if (sysvbackground) {
- def_sigquit = SIG_IGN;
- fnassign("sigquit", NULL); /* ignore */
- } else {
- def_sigquit = SIG_DFL;
- goto sigcommon;
- }
- break;
- case SIGTERM:
- def_sigterm = SIG_DFL;
- /* FALLTHROUGH */
- sigcommon:
- default:
- if (sighandlers[i] != SIG_DFL) {
- rc_signal(i, SIG_DFL);
- delete_fn(signals[i].name);
- }
- }
- }
- delete_fn("sigexit");
- runexit = FALSE; /* No sigexit on subshells */
-}
-
-/* rc's exit. if runexit is set, run the sigexit function. */
-
-extern void rc_exit(int stat) {
- if (runexit) {
- char *sig[2];
- sig[0] = "sigexit";
- sig[1] = NULL;
- runexit = FALSE;
- funcall(sig);
- stat = getstatus();
- }
- exit(stat);
-}
-
-/* The signal handler for all functions. calls walk() */
-
-static void fn_handler(int s) {
- char *sig[2];
- int olderrno;
- if (s < 1 || s >= NUMOFSIGNALS)
- panic("unknown signal");
- olderrno = errno;
- sig[0] = signals[s].name;
- sig[1] = NULL;
- funcall(sig);
- errno = olderrno;
-}
-
-/* A dud signal handler for SIGQUIT and SIGTERM */
-
-static void dud_handler(int s) {
-}
-
-/*
- Assign a function in Node form. Check to see if the function is also
- a signal, and set the signal vectors appropriately.
-*/
-
-extern void fnassign(char *name, Node *def) {
- Node *newdef = treecpy(def == NULL ? &null : def, ealloc); /* important to do the treecopy first */
- Function *new = get_fn_place(name);
- int i;
- new->def = newdef;
- new->extdef = NULL;
- if (strncmp(name, "sig", conststrlen("sig")) == 0) { /* slight optimization */
-#ifndef HAVE_RESTARTABLE_SYSCALLS /* System V machines treat SIGCLD very specially */
- if (streq(name, "sigcld"))
- rc_error("can't trap SIGCLD");
-#endif
- if (streq(name, "sigexit"))
- runexit = TRUE;
- for (i = 1; i < NUMOFSIGNALS; i++) /* zero is a bogus signal */
- if (streq(signals[i].name, name)) {
- handlers[i] = newdef;
- if (def == NULL)
- rc_signal(i, SIG_IGN);
- else
- rc_signal(i, fn_handler);
- break;
- }
- }
-}
-
-/* Assign a function from the environment. Store just the external representation */
-
-extern void fnassign_string(char *extdef) {
- char *name = get_name(extdef+3); /* +3 to skip over "fn_" */
- Function *new;
- if (name == NULL)
- return;
- new = get_fn_place(name);
- new->def = NULL;
- new->extdef = ecpy(extdef);
-}
-
-/* Return a function in Node form, evaluating an entry from the environment if necessary */
-
-extern Node *fnlookup(char *name) {
- Function *look = lookup_fn(name);
- Node *ret;
- if (look == NULL)
- return NULL; /* not found */
- if (look->def != NULL)
- return look->def;
- if (look->extdef == NULL) /* function was set to null, e.g., fn foo {} */
- return &null;
- ret = parse_fn(name, look->extdef);
- if (ret == NULL) {
- efree(look->extdef);
- look->extdef = NULL;
- return &null;
- } else {
- return look->def = treecpy(ret, ealloc); /* Need to take it out of nalloc space */
- }
-}
-
-/* Return a function in string form (used by makeenv) */
-
-extern char *fnlookup_string(char *name) {
- Function *look = lookup_fn(name);
-
- if (look == NULL)
- return NULL;
- if (look->extdef != NULL)
- return look->extdef;
- return look->extdef = mprint("fn_%F={%T}", name, look->def);
-}
-
-/*
- Remove a function from the symbol table. If it also defines a signal
- handler, restore the signal handler to its default value.
-*/
-
-extern void fnrm(char *name) {
- int i;
- for (i = 1; i < NUMOFSIGNALS; i++)
- if (streq(signals[i].name, name)) {
- handlers[i] = NULL;
- switch (i) {
- case SIGINT:
- rc_signal(i, def_sigint);
- break;
- case SIGQUIT:
- rc_signal(i, def_sigquit);
- break;
- case SIGTERM:
- rc_signal(i, def_sigterm);
- break;
- default:
- rc_signal(i, SIG_DFL);
- }
- }
- if (streq(name, "sigexit"))
- runexit = FALSE;
- delete_fn(name);
-}
-
-extern void whatare_all_signals() {
- int i;
- for (i = 1; i < NUMOFSIGNALS; i++)
- if (*signals[i].name != '\0')
- if (sighandlers[i] == SIG_IGN)
- fprint(1, "fn %s {}\n", signals[i].name);
- else if (sighandlers[i] == fn_handler)
- fprint(1, "fn %S {%T}\n", signals[i].name, handlers[i]);
- else
- fprint(1, "fn %s\n", signals[i].name);
-}
-
-extern void prettyprint_fn(int fd, char *name, Node *n) {
- fprint(fd, "fn %S {%T}\n", name, n);
-}