Annotation of src/usr.bin/pmdb/signal.c, Revision 1.2
1.2 ! jason 1: /* $OpenBSD: signal.c,v 1.10 2002/03/07 13:56:56 art Exp $ */
1.1 art 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: }