Annotation of src/usr.bin/pmdb/signal.c, Revision 1.1
1.1 ! art 1: /* $PMDB: signal.c,v 1.10 2002/03/07 13:56:56 art Exp $ */
! 2: /*
! 3: * Copyright (c) 2002 Artur Grabowski <art@openbsd.org>
! 4: * All rights reserved.
! 5: *
! 6: * Redistribution and use in source and binary forms, with or without
! 7: * modification, are permitted provided that the following conditions
! 8: * are met:
! 9: *
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: * 2. The name of the author may not be used to endorse or promote products
! 13: * derived from this software without specific prior written permission.
! 14: *
! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
! 16: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
! 17: * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
! 18: * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
! 19: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
! 20: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
! 21: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
! 22: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
! 23: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
! 24: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 25: */
! 26:
! 27: #include <stdlib.h>
! 28: #include <stdio.h>
! 29: #include <unistd.h>
! 30: #include <signal.h>
! 31: #include <string.h>
! 32: #include <sys/wait.h>
! 33:
! 34: #include "pmdb.h"
! 35:
! 36: void
! 37: init_sigstate(struct pstate *ps)
! 38: {
! 39: int i;
! 40:
! 41: for (i = 1; i < NSIG; i++)
! 42: ps->ps_sigstate[i] = SS_STOP;
! 43:
! 44: /* XXX - add more default ignored signals. */
! 45: ps->ps_sigstate[SIGALRM] = SS_IGNORE;
! 46: ps->ps_sigstate[SIGCHLD] = SS_IGNORE;
! 47: }
! 48:
! 49: void
! 50: process_signal(struct pstate *ps, int signum, int stopped, int force_ignore)
! 51: {
! 52: int ignore, status;
! 53:
! 54: if (stopped && (ps->ps_sigstate[signum] == SS_IGNORE || force_ignore))
! 55: ignore = 1;
! 56: else
! 57: ignore = 0;
! 58:
! 59: if (force_ignore && ignore)
! 60: signum = 0;
! 61:
! 62: ps->ps_signum = signum;
! 63:
! 64: if (!stopped) {
! 65: /*
! 66: * Process terminated.
! 67: */
! 68: /* Let it be restarted if it wasn't a forced termination. */
! 69: if ((ps->ps_flags & PSF_KILL) == 0)
! 70: ps->ps_state = NONE;
! 71: else
! 72: ps->ps_state = TERMINATED;
! 73: /*
! 74: * Wait for it as a parent.
! 75: * XXX - only if we're the real parent.
! 76: */
! 77: wait(&status);
! 78: } else {
! 79: ps->ps_state = STOPPED;
! 80: }
! 81:
! 82: if (!ignore) {
! 83: fprintf(stderr, "PBMD %s child. signal: %s\n",
! 84: stopped ? "stopping" : "terminating",
! 85: sys_signame[signum]);
! 86: } else {
! 87: cmd_process_cont(0, NULL, ps);
! 88: }
! 89: }
! 90:
! 91: int
! 92: cmd_signal_ignore(int argc, char **argv, void *arg)
! 93: {
! 94: struct pstate *ps = arg;
! 95: int signum;
! 96: long l;
! 97: char *ep;
! 98: char *signame = argv[2];
! 99: int newstate;
! 100:
! 101: if (!strcmp(argv[1], "ignore")) {
! 102: newstate = SS_IGNORE;
! 103: } else if (!strcmp(argv[1], "stop")) {
! 104: newstate = SS_STOP;
! 105: } else {
! 106: goto usage;
! 107: }
! 108:
! 109: l = strtol(signame, &ep, 0);
! 110: if (signame[0] == '\0' || *ep != '\0' || l < 1 || l > NSIG) {
! 111: if (!strncmp("SIG", signame, 3))
! 112: signame += 3;
! 113: for (signum = 1; signum < NSIG; signum++) {
! 114: if (!strcmp(sys_signame[signum], signame))
! 115: break;
! 116: }
! 117: } else {
! 118: signum = l;
! 119: }
! 120:
! 121: switch (signum) {
! 122: case SIGINT:
! 123: case SIGSTOP:
! 124: case SIGKILL:
! 125: fprintf(stderr, "%s can't be ignored\n", signame);
! 126: goto usage;
! 127: case NSIG:
! 128: fprintf(stderr, "%s is not a valid signal\n", signame);
! 129: goto usage;
! 130: default:
! 131: break;
! 132: }
! 133:
! 134: ps->ps_sigstate[signum] = newstate;
! 135:
! 136: return 0;
! 137: usage:
! 138: fprintf(stderr, "Usage: signal <ignore|stop> <signum|signame>\n");
! 139: return 0;
! 140: }
! 141:
! 142: int
! 143: cmd_signal_show(int argc, char **argv, void *arg)
! 144: {
! 145: struct pstate *ps = arg;
! 146: int i;
! 147:
! 148: for (i = 1; i < NSIG; i++) {
! 149: char *state;
! 150:
! 151: switch (ps->ps_sigstate[i]) {
! 152: case SS_STOP:
! 153: state = "stop";
! 154: break;
! 155: case SS_IGNORE:
! 156: state = "ignore";
! 157: break;
! 158: default:
! 159: state = "error";
! 160: break;
! 161: }
! 162: printf("%2d %-6s\t%s\n", i, sys_signame[i], state);
! 163: }
! 164:
! 165: return 0;
! 166: }