xref: /minix3/minix/tests/test37.c (revision cbc8a0df90ec437bc4bf50316f902f29128579e1)
1433d6423SLionel Sambuc /* test 37 - signals */
2433d6423SLionel Sambuc 
3433d6423SLionel Sambuc #include <sys/types.h>
4433d6423SLionel Sambuc #include <sys/times.h>
5433d6423SLionel Sambuc #include <sys/wait.h>
6433d6423SLionel Sambuc #include <errno.h>
7433d6423SLionel Sambuc #include <signal.h>
8433d6423SLionel Sambuc #include <setjmp.h>
9433d6423SLionel Sambuc #include <stdlib.h>
10433d6423SLionel Sambuc #include <unistd.h>
11433d6423SLionel Sambuc #include <stdio.h>
12433d6423SLionel Sambuc #include <assert.h>
13433d6423SLionel Sambuc 
14433d6423SLionel Sambuc #define ITERATIONS 2
15433d6423SLionel Sambuc #define SIGS 14
16433d6423SLionel Sambuc int max_error = 4;
17433d6423SLionel Sambuc #include "common.h"
18433d6423SLionel Sambuc 
19433d6423SLionel Sambuc 
20433d6423SLionel Sambuc 
21433d6423SLionel Sambuc int iteration, cumsig, sig1, sig2;
22433d6423SLionel Sambuc 
23433d6423SLionel Sambuc int sigarray[SIGS] = {SIGHUP, SIGILL, SIGTRAP, SIGABRT, SIGIOT,
24433d6423SLionel Sambuc 	      SIGFPE, SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM,
25433d6423SLionel Sambuc 	      SIGTERM};
26433d6423SLionel Sambuc 
27433d6423SLionel Sambuc /* Prototypes produced automatically by mkptypes. */
28433d6423SLionel Sambuc int main(int argc, char *argv []);
29433d6423SLionel Sambuc void test37a(void);
30433d6423SLionel Sambuc void func1(int sig);
31433d6423SLionel Sambuc void func2(int sig);
32433d6423SLionel Sambuc void test37b(void);
33433d6423SLionel Sambuc void catch1(int signo);
34433d6423SLionel Sambuc void catch2(int signo);
35433d6423SLionel Sambuc void test37c(void);
36433d6423SLionel Sambuc void catch3(int signo);
37433d6423SLionel Sambuc void test37d(void);
38433d6423SLionel Sambuc void catch4(int signo);
39433d6423SLionel Sambuc void test37e(void);
40433d6423SLionel Sambuc void catch5(int signo);
41433d6423SLionel Sambuc void test37f(void);
42433d6423SLionel Sambuc void sigint_handler(int signo);
43433d6423SLionel Sambuc void sigpipe_handler(int signo);
44433d6423SLionel Sambuc void test37g(void);
45433d6423SLionel Sambuc void sighup8(int signo);
46433d6423SLionel Sambuc void sigpip8(int signo);
47433d6423SLionel Sambuc void sigter8(int signo);
48433d6423SLionel Sambuc void test37h(void);
49433d6423SLionel Sambuc void sighup9(int signo);
50433d6423SLionel Sambuc void sigter9(int signo);
51433d6423SLionel Sambuc void test37i(void);
52433d6423SLionel Sambuc void sighup10(int signo);
53433d6423SLionel Sambuc void sigalrm_handler10(int signo);
54433d6423SLionel Sambuc void test37j(void);
55433d6423SLionel Sambuc void test37k(void);
56433d6423SLionel Sambuc void test37l(void);
57433d6423SLionel Sambuc void func_m1(void);
58433d6423SLionel Sambuc void func_m2(void);
59433d6423SLionel Sambuc void test37m(void);
60433d6423SLionel Sambuc void test37p(void);
61433d6423SLionel Sambuc void test37q(void);
62433d6423SLionel Sambuc void longjerr(void);
63433d6423SLionel Sambuc void catch14(int signo, int code, struct sigcontext * scp);
64433d6423SLionel Sambuc void test37n(void);
65433d6423SLionel Sambuc void catch15(int signo);
66433d6423SLionel Sambuc void test37o(void);
67433d6423SLionel Sambuc void clearsigstate(void);
68433d6423SLionel Sambuc void wait_for(int pid);
69433d6423SLionel Sambuc 
main(argc,argv)70433d6423SLionel Sambuc int main(argc, argv)
71433d6423SLionel Sambuc int argc;
72433d6423SLionel Sambuc char *argv[];
73433d6423SLionel Sambuc {
74433d6423SLionel Sambuc   int i, m = 0377777;
75433d6423SLionel Sambuc 
76433d6423SLionel Sambuc   sync();
77433d6423SLionel Sambuc 
78433d6423SLionel Sambuc   start(37);
79433d6423SLionel Sambuc 
80433d6423SLionel Sambuc   if (argc == 2) m = atoi(argv[1]);
81433d6423SLionel Sambuc 
82433d6423SLionel Sambuc   for (i = 0; i < ITERATIONS; i++) {
83433d6423SLionel Sambuc 	iteration = i;
84433d6423SLionel Sambuc 	if (m & 0000001) test37a();
85433d6423SLionel Sambuc 	if (m & 0000002) test37b();
86433d6423SLionel Sambuc 	if (m & 0000004) test37c();
87433d6423SLionel Sambuc 	if (m & 0000010) test37d();
88433d6423SLionel Sambuc 	if (m & 0000020) test37e();
89433d6423SLionel Sambuc 	if (m & 0000040) test37f();
90433d6423SLionel Sambuc 	if (m & 0000100) test37g();
91433d6423SLionel Sambuc 	if (m & 0000200) test37h();
92433d6423SLionel Sambuc 	if (m & 0000400) test37i();
93433d6423SLionel Sambuc 	if (m & 0001000) test37j();
94433d6423SLionel Sambuc 	if (m & 0002000) test37k();
95433d6423SLionel Sambuc 	if (m & 0004000) test37l();
96433d6423SLionel Sambuc 	if (m & 0010000) test37m();
97433d6423SLionel Sambuc 	if (m & 0020000) test37n();
98433d6423SLionel Sambuc 	if (m & 0040000) test37o();
99433d6423SLionel Sambuc 	if (m & 0100000) test37p();
100433d6423SLionel Sambuc 	if (m & 0200000) test37q();
101433d6423SLionel Sambuc   }
102433d6423SLionel Sambuc 
103433d6423SLionel Sambuc   quit();
104433d6423SLionel Sambuc 
105433d6423SLionel Sambuc   return(-1);	/* Unreachable */
106433d6423SLionel Sambuc }
107433d6423SLionel Sambuc 
test37a()108433d6423SLionel Sambuc void test37a()
109433d6423SLionel Sambuc {
110433d6423SLionel Sambuc /* Test signal set management. */
111433d6423SLionel Sambuc 
112433d6423SLionel Sambuc   sigset_t s;
113433d6423SLionel Sambuc 
114433d6423SLionel Sambuc   subtest = 1;
115433d6423SLionel Sambuc   clearsigstate();
116433d6423SLionel Sambuc 
117433d6423SLionel Sambuc   /* Create an empty set and see if any bits are on. */
118433d6423SLionel Sambuc   if (sigemptyset(&s) != 0) e(1);
119433d6423SLionel Sambuc   if (sigismember(&s, SIGHUP) != 0) e(2);
120433d6423SLionel Sambuc   if (sigismember(&s, SIGINT) != 0) e(3);
121433d6423SLionel Sambuc   if (sigismember(&s, SIGQUIT) != 0) e(4);
122433d6423SLionel Sambuc   if (sigismember(&s, SIGILL) != 0) e(5);
123433d6423SLionel Sambuc   if (sigismember(&s, SIGTRAP) != 0) e(6);
124433d6423SLionel Sambuc   if (sigismember(&s, SIGABRT) != 0) e(7);
125433d6423SLionel Sambuc   if (sigismember(&s, SIGIOT) != 0) e(8);
126433d6423SLionel Sambuc   if (sigismember(&s, SIGFPE) != 0) e(10);
127433d6423SLionel Sambuc   if (sigismember(&s, SIGKILL) != 0) e(11);
128433d6423SLionel Sambuc   if (sigismember(&s, SIGUSR1) != 0) e(12);
129433d6423SLionel Sambuc   if (sigismember(&s, SIGSEGV) != 0) e(13);
130433d6423SLionel Sambuc   if (sigismember(&s, SIGUSR2) != 0) e(14);
131433d6423SLionel Sambuc   if (sigismember(&s, SIGPIPE) != 0) e(15);
132433d6423SLionel Sambuc   if (sigismember(&s, SIGALRM) != 0) e(16);
133433d6423SLionel Sambuc   if (sigismember(&s, SIGTERM) != 0) e(17);
134433d6423SLionel Sambuc   if (sigismember(&s, SIGPWR) != 0) e(17);
135433d6423SLionel Sambuc 
136433d6423SLionel Sambuc   /* Create a full set and see if any bits are off. */
137433d6423SLionel Sambuc   if (sigfillset(&s) != 0) e(19);
138433d6423SLionel Sambuc   if (sigemptyset(&s) != 0) e(20);
139433d6423SLionel Sambuc   if (sigfillset(&s) != 0) e(21);
140433d6423SLionel Sambuc   if (sigismember(&s, SIGHUP) != 1) e(22);
141433d6423SLionel Sambuc   if (sigismember(&s, SIGINT) != 1) e(23);
142433d6423SLionel Sambuc   if (sigismember(&s, SIGQUIT) != 1) e(24);
143433d6423SLionel Sambuc   if (sigismember(&s, SIGILL) != 1) e(25);
144433d6423SLionel Sambuc   if (sigismember(&s, SIGTRAP) != 1) e(26);
145433d6423SLionel Sambuc   if (sigismember(&s, SIGABRT) != 1) e(27);
146433d6423SLionel Sambuc   if (sigismember(&s, SIGIOT) != 1) e(28);
147433d6423SLionel Sambuc   if (sigismember(&s, SIGFPE) != 1) e(30);
148433d6423SLionel Sambuc   if (sigismember(&s, SIGKILL) != 1) e(31);
149433d6423SLionel Sambuc   if (sigismember(&s, SIGUSR1) != 1) e(32);
150433d6423SLionel Sambuc   if (sigismember(&s, SIGSEGV) != 1) e(33);
151433d6423SLionel Sambuc   if (sigismember(&s, SIGUSR2) != 1) e(34);
152433d6423SLionel Sambuc   if (sigismember(&s, SIGPIPE) != 1) e(35);
153433d6423SLionel Sambuc   if (sigismember(&s, SIGALRM) != 1) e(36);
154433d6423SLionel Sambuc   if (sigismember(&s, SIGTERM) != 1) e(37);
155433d6423SLionel Sambuc   if (sigismember(&s, SIGPWR) != 1) e(37);
156433d6423SLionel Sambuc 
157433d6423SLionel Sambuc   /* Create an empty set, then turn on bits individually. */
158433d6423SLionel Sambuc   if (sigemptyset(&s) != 0) e(39);
159433d6423SLionel Sambuc   if (sigaddset(&s, SIGHUP) != 0) e(40);
160433d6423SLionel Sambuc   if (sigaddset(&s, SIGINT) != 0) e(41);
161433d6423SLionel Sambuc   if (sigaddset(&s, SIGQUIT) != 0) e(42);
162433d6423SLionel Sambuc   if (sigaddset(&s, SIGILL) != 0) e(43);
163433d6423SLionel Sambuc   if (sigaddset(&s, SIGTRAP) != 0) e(44);
164433d6423SLionel Sambuc   if (sigaddset(&s, SIGPWR) != 0) e(44);
165433d6423SLionel Sambuc 
166433d6423SLionel Sambuc   /* See if the bits just turned on are indeed on. */
167433d6423SLionel Sambuc   if (sigismember(&s, SIGHUP) != 1) e(45);
168433d6423SLionel Sambuc   if (sigismember(&s, SIGINT) != 1) e(46);
169433d6423SLionel Sambuc   if (sigismember(&s, SIGQUIT) != 1) e(47);
170433d6423SLionel Sambuc   if (sigismember(&s, SIGILL) != 1) e(48);
171433d6423SLionel Sambuc   if (sigismember(&s, SIGTRAP) != 1) e(49);
172433d6423SLionel Sambuc   if (sigismember(&s, SIGPWR) != 1) e(49);
173433d6423SLionel Sambuc 
174433d6423SLionel Sambuc   /* The others should be turned off. */
175433d6423SLionel Sambuc   if (sigismember(&s, SIGABRT) != 0) e(50);
176433d6423SLionel Sambuc   if (sigismember(&s, SIGIOT) != 0) e(51);
177433d6423SLionel Sambuc   if (sigismember(&s, SIGFPE) != 0) e(53);
178433d6423SLionel Sambuc   if (sigismember(&s, SIGKILL) != 0) e(54);
179433d6423SLionel Sambuc   if (sigismember(&s, SIGUSR1) != 0) e(55);
180433d6423SLionel Sambuc   if (sigismember(&s, SIGSEGV) != 0) e(56);
181433d6423SLionel Sambuc   if (sigismember(&s, SIGUSR2) != 0) e(57);
182433d6423SLionel Sambuc   if (sigismember(&s, SIGPIPE) != 0) e(58);
183433d6423SLionel Sambuc   if (sigismember(&s, SIGALRM) != 0) e(59);
184433d6423SLionel Sambuc   if (sigismember(&s, SIGTERM) != 0) e(60);
185433d6423SLionel Sambuc 
186433d6423SLionel Sambuc   /* Now turn them off and see if all are off. */
187433d6423SLionel Sambuc   if (sigdelset(&s, SIGHUP) != 0) e(62);
188433d6423SLionel Sambuc   if (sigdelset(&s, SIGINT) != 0) e(63);
189433d6423SLionel Sambuc   if (sigdelset(&s, SIGQUIT) != 0) e(64);
190433d6423SLionel Sambuc   if (sigdelset(&s, SIGILL) != 0) e(65);
191433d6423SLionel Sambuc   if (sigdelset(&s, SIGTRAP) != 0) e(66);
192433d6423SLionel Sambuc   if (sigdelset(&s, SIGPWR) != 0) e(66);
193433d6423SLionel Sambuc 
194433d6423SLionel Sambuc   if (sigismember(&s, SIGHUP) != 0) e(67);
195433d6423SLionel Sambuc   if (sigismember(&s, SIGINT) != 0) e(68);
196433d6423SLionel Sambuc   if (sigismember(&s, SIGQUIT) != 0) e(69);
197433d6423SLionel Sambuc   if (sigismember(&s, SIGILL) != 0) e(70);
198433d6423SLionel Sambuc   if (sigismember(&s, SIGTRAP) != 0) e(71);
199433d6423SLionel Sambuc   if (sigismember(&s, SIGABRT) != 0) e(72);
200433d6423SLionel Sambuc   if (sigismember(&s, SIGIOT) != 0) e(73);
201433d6423SLionel Sambuc   if (sigismember(&s, SIGFPE) != 0) e(75);
202433d6423SLionel Sambuc   if (sigismember(&s, SIGKILL) != 0) e(76);
203433d6423SLionel Sambuc   if (sigismember(&s, SIGUSR1) != 0) e(77);
204433d6423SLionel Sambuc   if (sigismember(&s, SIGSEGV) != 0) e(78);
205433d6423SLionel Sambuc   if (sigismember(&s, SIGUSR2) != 0) e(79);
206433d6423SLionel Sambuc   if (sigismember(&s, SIGPIPE) != 0) e(80);
207433d6423SLionel Sambuc   if (sigismember(&s, SIGALRM) != 0) e(81);
208433d6423SLionel Sambuc   if (sigismember(&s, SIGTERM) != 0) e(82);
209433d6423SLionel Sambuc   if (sigismember(&s, SIGPWR) != 0) e(82);
210433d6423SLionel Sambuc }
211433d6423SLionel Sambuc 
func1(sig)212433d6423SLionel Sambuc void func1(sig)
213433d6423SLionel Sambuc int sig;
214433d6423SLionel Sambuc {
215433d6423SLionel Sambuc   sig1++;
216433d6423SLionel Sambuc }
217433d6423SLionel Sambuc 
func2(sig)218433d6423SLionel Sambuc void func2(sig)
219433d6423SLionel Sambuc int sig;
220433d6423SLionel Sambuc {
221433d6423SLionel Sambuc   sig2++;
222433d6423SLionel Sambuc }
223433d6423SLionel Sambuc 
224433d6423SLionel Sambuc 
sigmemcmp(sigset_t * s1,sigset_t * s2,int size)225*cbc8a0dfSDavid van Moolenbroek static int sigmemcmp(sigset_t *s1, sigset_t *s2, int size)
226433d6423SLionel Sambuc {
227433d6423SLionel Sambuc 	int i;
228433d6423SLionel Sambuc 	int mismatch = 0;
229433d6423SLionel Sambuc 	assert(size == sizeof(sigset_t));
230433d6423SLionel Sambuc 	for(i = 1; i < _NSIG; i++) {
231433d6423SLionel Sambuc 		if(sigismember(s1, i) && !sigismember(s2, i)) {
232433d6423SLionel Sambuc 			fprintf(stderr, "sig %d set in first but not in 2nd\n", i);
233433d6423SLionel Sambuc 			mismatch = 1;
234433d6423SLionel Sambuc 		}
235433d6423SLionel Sambuc 		if(!sigismember(s1, i) && sigismember(s2, i)) {
236433d6423SLionel Sambuc 			fprintf(stderr, "sig %d not set in first but is in 2nd\n", i);
237433d6423SLionel Sambuc 			mismatch = 1;
238433d6423SLionel Sambuc 		}
239433d6423SLionel Sambuc 	}
240433d6423SLionel Sambuc 
241433d6423SLionel Sambuc 	return mismatch;
242433d6423SLionel Sambuc }
243433d6423SLionel Sambuc 
test37b()244433d6423SLionel Sambuc void test37b()
245433d6423SLionel Sambuc {
246433d6423SLionel Sambuc /* Test sigprocmask and sigpending. */
247433d6423SLionel Sambuc   int i;
248433d6423SLionel Sambuc   pid_t p;
249433d6423SLionel Sambuc   sigset_t s, s1, s_empty, s_full, s_ill, s_ill_pip, s_nokill, s_nokill_stop;
250433d6423SLionel Sambuc   struct sigaction sa, osa;
251433d6423SLionel Sambuc 
252433d6423SLionel Sambuc   subtest = 2;
253433d6423SLionel Sambuc   clearsigstate();
254433d6423SLionel Sambuc 
255433d6423SLionel Sambuc   /* Construct s_ill = {SIGILL} and s_ill_pip {SIGILL | SIGPIP}, etc. */
256433d6423SLionel Sambuc   if (sigemptyset(&s_empty) != 0) e(1);
257433d6423SLionel Sambuc   if (sigemptyset(&s_ill) != 0) e(2);
258433d6423SLionel Sambuc   if (sigemptyset(&s_ill_pip) != 0) e(3);
259433d6423SLionel Sambuc   if (sigaddset(&s_ill, SIGILL) != 0) e(4);
260433d6423SLionel Sambuc   if (sigaddset(&s_ill_pip, SIGILL) != 0) e(5);
261433d6423SLionel Sambuc   if (sigaddset(&s_ill_pip, SIGPIPE) != 0) e(6);
262433d6423SLionel Sambuc   if (sigfillset(&s_full) != 0) e(7);
263433d6423SLionel Sambuc   s_nokill = s_full;
264433d6423SLionel Sambuc   if (sigdelset(&s_nokill, SIGKILL) != 0) e(8);
265433d6423SLionel Sambuc   s_nokill_stop = s_nokill;
266433d6423SLionel Sambuc   if (sigdelset(&s_nokill_stop, SIGSTOP) != 0) e(8);
267433d6423SLionel Sambuc   if (SIGSTOP >= _NSIG) e(666);
268433d6423SLionel Sambuc   if (SIGSTOP < _NSIG && sigdelset(&s_nokill, SIGSTOP) != 0) e(888);
269433d6423SLionel Sambuc 
270433d6423SLionel Sambuc   /* Now get most of the signals into default state.  Don't change SIGINT
271433d6423SLionel Sambuc   * or SIGQUIT, so this program can be killed.  SIGKILL is also special.
272433d6423SLionel Sambuc   */
273433d6423SLionel Sambuc   sa.sa_handler = SIG_DFL;
274433d6423SLionel Sambuc   sa.sa_mask = s_empty;
275433d6423SLionel Sambuc   sa.sa_flags = 0;
276433d6423SLionel Sambuc   for (i = 0; i < SIGS; i++) sigaction(i, &sa, &osa);
277433d6423SLionel Sambuc 
278433d6423SLionel Sambuc   /* The second argument may be zero.  See if it wipes out the system. */
279433d6423SLionel Sambuc   for (i = 0; i < SIGS; i++) sigaction(i, (struct sigaction *) NULL, &osa);
280433d6423SLionel Sambuc 
281433d6423SLionel Sambuc   /* Install a signal handler. */
282433d6423SLionel Sambuc   sa.sa_handler = func1;
283433d6423SLionel Sambuc   sa.sa_mask = s_ill;
284433d6423SLionel Sambuc   sa.sa_flags = SA_NODEFER | SA_NOCLDSTOP;
285433d6423SLionel Sambuc   osa.sa_handler = SIG_IGN;
286433d6423SLionel Sambuc   osa.sa_mask = s_empty;
287433d6423SLionel Sambuc   osa.sa_flags = 0;
288433d6423SLionel Sambuc   if (sigaction(SIGHUP, &sa, &osa) != 0) e(9);
289433d6423SLionel Sambuc   if (osa.sa_handler != SIG_DFL) e(10);
290433d6423SLionel Sambuc   if (sigmemcmp(&osa.sa_mask, &s_empty, sizeof(s_empty))) e(11);
291433d6423SLionel Sambuc   if (osa.sa_flags != 0) e(12);
292433d6423SLionel Sambuc 
293433d6423SLionel Sambuc   /* Replace action and see if old value is read back correctly. */
294433d6423SLionel Sambuc   sa.sa_handler = func2;
295433d6423SLionel Sambuc   sa.sa_mask = s_ill_pip;
296433d6423SLionel Sambuc   sa.sa_flags = SA_RESETHAND | SA_NODEFER;
297433d6423SLionel Sambuc   osa.sa_handler = SIG_IGN;
298433d6423SLionel Sambuc   osa.sa_mask = s_empty;
299433d6423SLionel Sambuc   osa.sa_flags = 0;
300433d6423SLionel Sambuc   if (sigaction(SIGHUP, &sa, &osa) != 0) e(13);
301433d6423SLionel Sambuc   if (osa.sa_handler != func1) e(14);
302433d6423SLionel Sambuc   if (sigmemcmp(&osa.sa_mask, &s_ill, sizeof(s_ill))) e(15);
303433d6423SLionel Sambuc   if (osa.sa_flags != SA_NODEFER
304433d6423SLionel Sambuc       && osa.sa_flags != (SA_NODEFER | SA_NOCLDSTOP)) e(16);
305433d6423SLionel Sambuc 
306433d6423SLionel Sambuc   /* Replace action once more and check what is read back. */
307433d6423SLionel Sambuc   sa.sa_handler = SIG_DFL;
308433d6423SLionel Sambuc   sa.sa_mask = s_empty;
309433d6423SLionel Sambuc   osa.sa_handler = SIG_IGN;
310433d6423SLionel Sambuc   osa.sa_mask = s_empty;
311433d6423SLionel Sambuc   osa.sa_flags = 0;
312433d6423SLionel Sambuc   if (sigaction(SIGHUP, &sa, &osa) != 0) e(17);
313433d6423SLionel Sambuc   if (osa.sa_handler != func2) e(18);
314433d6423SLionel Sambuc   if (sigmemcmp(&osa.sa_mask, &s_ill_pip, sizeof(s_ill_pip))) e(19);
315433d6423SLionel Sambuc   if (osa.sa_flags != (SA_RESETHAND | SA_NODEFER)) e(20);
316433d6423SLionel Sambuc 
317433d6423SLionel Sambuc   /* Test sigprocmask(SIG_SETMASK, ...). */
318433d6423SLionel Sambuc   if (sigprocmask(SIG_SETMASK, &s_full, &s1) != 0) e(18);    /* block all */
319433d6423SLionel Sambuc   if (sigemptyset(&s1) != 0) e(19);
320433d6423SLionel Sambuc   errno = 0;
321433d6423SLionel Sambuc   if (sigprocmask(SIG_SETMASK, &s_empty, &s1) != 0) e(20);   /* block none */
322433d6423SLionel Sambuc   if (sigmemcmp(&s1, &s_nokill_stop, sizeof(s1))) e(21);
323433d6423SLionel Sambuc   if (sigprocmask(SIG_SETMASK, &s_ill, &s1) != 0) e(22);     /* block SIGILL */
324433d6423SLionel Sambuc   errno = 0;
325433d6423SLionel Sambuc   if (sigmemcmp(&s1, &s_empty, sizeof(s1))) e(23);
326433d6423SLionel Sambuc   if (sigprocmask(SIG_SETMASK, &s_ill_pip, &s1) != 0) e(24); /* SIGILL+PIP */
327433d6423SLionel Sambuc   if (sigmemcmp(&s1, &s_ill, sizeof(s1))) e(25);
328433d6423SLionel Sambuc   if (sigprocmask(SIG_SETMASK, &s_full, &s1) != 0) e(26);    /* block all */
329433d6423SLionel Sambuc   if (sigmemcmp(&s1, &s_ill_pip, sizeof(s1))) e(27);
330433d6423SLionel Sambuc 
331433d6423SLionel Sambuc   /* Test sigprocmask(SIG_UNBLOCK, ...) */
332433d6423SLionel Sambuc   if (sigprocmask(SIG_UNBLOCK, &s_ill, &s1) != 0) e(28);
333433d6423SLionel Sambuc   if (sigmemcmp(&s1, &s_nokill_stop, sizeof(s1))) e(29);
334433d6423SLionel Sambuc   if (sigprocmask(SIG_UNBLOCK, &s_ill_pip, &s1) != 0) e(30);
335433d6423SLionel Sambuc   s = s_nokill_stop;
336433d6423SLionel Sambuc   if (sigdelset(&s, SIGILL) != 0) e(31);
337433d6423SLionel Sambuc   if (sigmemcmp(&s, &s1, sizeof(s))) e(32);
338433d6423SLionel Sambuc   if (sigprocmask(SIG_UNBLOCK, &s_empty, &s1) != 0) e(33);
339433d6423SLionel Sambuc   s = s_nokill_stop;
340433d6423SLionel Sambuc   if (sigdelset(&s, SIGILL) != 0) e(34);
341433d6423SLionel Sambuc   if (sigdelset(&s, SIGPIPE) != 0) e(35);
342433d6423SLionel Sambuc   if (sigmemcmp(&s, &s1, sizeof(s))) e(36);
343433d6423SLionel Sambuc   s1 = s_nokill_stop;
344433d6423SLionel Sambuc   if (sigprocmask(SIG_SETMASK, &s_empty, &s1) != 0) e(37);
345433d6423SLionel Sambuc   if (sigmemcmp(&s, &s1, sizeof(s))) e(38);
346433d6423SLionel Sambuc 
347433d6423SLionel Sambuc   /* Test sigprocmask(SIG_BLOCK, ...) */
348433d6423SLionel Sambuc   if (sigprocmask(SIG_BLOCK, &s_ill, &s1) != 0) e(39);
349433d6423SLionel Sambuc   if (sigmemcmp(&s1, &s_empty, sizeof(s1))) e(40);
350433d6423SLionel Sambuc   if (sigprocmask(SIG_BLOCK, &s_ill_pip, &s1) != 0) e(41);
351433d6423SLionel Sambuc   if (sigmemcmp(&s1, &s_ill, sizeof(s1))) e(42);
352433d6423SLionel Sambuc   if (sigprocmask(SIG_SETMASK, &s_full, &s1) != 0) e(43);
353433d6423SLionel Sambuc   if (sigmemcmp(&s1, &s_ill_pip, sizeof(s1))) e(44);
354433d6423SLionel Sambuc 
355433d6423SLionel Sambuc   /* Check error condition. */
356433d6423SLionel Sambuc   errno = 0;
357433d6423SLionel Sambuc   if (sigprocmask(20000, &s_full, &s1) != -1) e(45);
358433d6423SLionel Sambuc   if (errno != EINVAL) e(46);
359433d6423SLionel Sambuc   if (sigprocmask(SIG_SETMASK, &s_full, &s1) != 0) e(47);
360433d6423SLionel Sambuc   if (sigmemcmp(&s1, &s_nokill_stop, sizeof(s1))) e(48);
361433d6423SLionel Sambuc 
362433d6423SLionel Sambuc   /* If second arg is 0, nothing is set. */
363433d6423SLionel Sambuc   if (sigprocmask(SIG_SETMASK, (sigset_t *) NULL, &s1) != 0) e(49);
364433d6423SLionel Sambuc   if (sigmemcmp(&s1, &s_nokill_stop, sizeof(s1))) e(50);
365433d6423SLionel Sambuc   if (sigprocmask(SIG_SETMASK, &s_ill_pip, &s1) != 0) e(51);
366433d6423SLionel Sambuc   if (sigmemcmp(&s1, &s_nokill_stop, sizeof(s1))) e(52);
367433d6423SLionel Sambuc   if (sigprocmask(SIG_SETMASK, (sigset_t *) NULL, &s1) != 0) e(53);
368433d6423SLionel Sambuc   if (sigmemcmp(&s1, &s_ill_pip, sizeof(s1))) e(54);
369433d6423SLionel Sambuc   if (sigprocmask(SIG_BLOCK, (sigset_t *) NULL, &s1) != 0) e(55);
370433d6423SLionel Sambuc   if (sigmemcmp(&s1, &s_ill_pip, sizeof(s1))) e(56);
371433d6423SLionel Sambuc   if (sigprocmask(SIG_UNBLOCK, (sigset_t *) NULL, &s1) != 0) e(57);
372433d6423SLionel Sambuc   if (sigmemcmp(&s1, &s_ill_pip, sizeof(s1))) e(58);
373433d6423SLionel Sambuc 
374433d6423SLionel Sambuc   /* Trying to block SIGKILL is not allowed, but is not an error, either. */
375433d6423SLionel Sambuc   s = s_empty;
376433d6423SLionel Sambuc   if (sigaddset(&s, SIGKILL) != 0) e(59);
377433d6423SLionel Sambuc   if (sigprocmask(SIG_BLOCK, &s, &s1) != 0) e(60);
378433d6423SLionel Sambuc   if (sigmemcmp(&s1, &s_ill_pip, sizeof(s1))) e(61);
379433d6423SLionel Sambuc   if (sigprocmask(SIG_SETMASK, &s_full, &s1) != 0) e(62);
380433d6423SLionel Sambuc   if (sigmemcmp(&s1, &s_ill_pip, sizeof(s1))) e(63);
381433d6423SLionel Sambuc 
382433d6423SLionel Sambuc   /* Test sigpending. At this moment, all signals are blocked. */
383433d6423SLionel Sambuc   sa.sa_handler = func2;
384433d6423SLionel Sambuc   sa.sa_mask = s_empty;
385433d6423SLionel Sambuc   if (sigaction(SIGHUP, &sa, &osa) != 0) e(64);
386433d6423SLionel Sambuc   p = getpid();
387433d6423SLionel Sambuc   kill(p, SIGHUP);		/* send SIGHUP to self */
388433d6423SLionel Sambuc   if (sigpending(&s) != 0) e(65);
389433d6423SLionel Sambuc   if (sigemptyset(&s1) != 0) e(66);
390433d6423SLionel Sambuc   if (sigaddset(&s1, SIGHUP) != 0) e(67);
391433d6423SLionel Sambuc   if (sigmemcmp(&s, &s1, sizeof(s))) e(68);
392433d6423SLionel Sambuc   sa.sa_handler = SIG_IGN;
393433d6423SLionel Sambuc   if (sigaction(SIGHUP, &sa, &osa) != 0) e(69);
394433d6423SLionel Sambuc   if (sigpending(&s) != 0) e(70);
395433d6423SLionel Sambuc   if (sigmemcmp(&s, &s_empty, sizeof(s))) e(71);
396433d6423SLionel Sambuc }
397433d6423SLionel Sambuc 
398433d6423SLionel Sambuc /*---------------------------------------------------------------------------*/
399433d6423SLionel Sambuc int x;
400433d6423SLionel Sambuc sigset_t glo_vol_set;
401433d6423SLionel Sambuc 
catch1(signo)402433d6423SLionel Sambuc void catch1(signo)
403433d6423SLionel Sambuc int signo;
404433d6423SLionel Sambuc {
405433d6423SLionel Sambuc   x = 42;
406433d6423SLionel Sambuc }
407433d6423SLionel Sambuc 
catch2(signo)408433d6423SLionel Sambuc void catch2(signo)
409433d6423SLionel Sambuc int signo;
410433d6423SLionel Sambuc {
411433d6423SLionel Sambuc   if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, (sigset_t *) &glo_vol_set) != 0)
412433d6423SLionel Sambuc 	e(1);
413433d6423SLionel Sambuc }
414433d6423SLionel Sambuc 
415433d6423SLionel Sambuc /* Verify that signal(2), which is now built on top of sigaction(2), still
416433d6423SLionel Sambuc * works.
417433d6423SLionel Sambuc */
test37c()418433d6423SLionel Sambuc void test37c()
419433d6423SLionel Sambuc {
420433d6423SLionel Sambuc   pid_t pid;
421433d6423SLionel Sambuc   sigset_t sigset_var;
422433d6423SLionel Sambuc 
423433d6423SLionel Sambuc   subtest = 3;
424433d6423SLionel Sambuc   clearsigstate();
425433d6423SLionel Sambuc   x = 0;
426433d6423SLionel Sambuc 
427433d6423SLionel Sambuc   /* Verify an installed signal handler persists across a fork(2). */
428433d6423SLionel Sambuc   if (signal(SIGTERM, catch1) == SIG_ERR) e(1);
429433d6423SLionel Sambuc   switch (pid = fork()) {
430433d6423SLionel Sambuc       case 0:			/* child */
431433d6423SLionel Sambuc 	errct = 0;
432433d6423SLionel Sambuc 	while (x == 0);
433433d6423SLionel Sambuc 	if (x != 42) e(2);
434433d6423SLionel Sambuc 	exit(errct == 0 ? 0 : 1);
435433d6423SLionel Sambuc       case -1:	e(3);	break;
436433d6423SLionel Sambuc       default:			/* parent */
437433d6423SLionel Sambuc 	sleep(1);
438433d6423SLionel Sambuc 	if (kill(pid, SIGTERM) != 0) e(4);
439433d6423SLionel Sambuc 	wait_for(pid);
440433d6423SLionel Sambuc 	break;
441433d6423SLionel Sambuc   }
442433d6423SLionel Sambuc 
443433d6423SLionel Sambuc   /* Verify that the return value is the previous handler. */
444433d6423SLionel Sambuc   signal(SIGINT, SIG_IGN);
445433d6423SLionel Sambuc   if (signal(SIGINT, catch2) != SIG_IGN) e(5);
446433d6423SLionel Sambuc   if (signal(SIGINT, catch1) != catch2) e(6);
447433d6423SLionel Sambuc   if (signal(SIGINT, SIG_DFL) != catch1) e(7);
448433d6423SLionel Sambuc   if (signal(SIGINT, catch1) != SIG_DFL) e(8);
449433d6423SLionel Sambuc   if (signal(SIGINT, SIG_DFL) != catch1) e(9);
450433d6423SLionel Sambuc   if (signal(SIGINT, SIG_DFL) != SIG_DFL) e(10);
451433d6423SLionel Sambuc   if (signal(SIGINT, catch1) != SIG_DFL) e(11);
452433d6423SLionel Sambuc 
453433d6423SLionel Sambuc   /* Verify that SIG_ERR is correctly generated. */
454433d6423SLionel Sambuc   if (signal(_NSIG, catch1) != SIG_ERR) e(12);
455433d6423SLionel Sambuc   if (signal(0, catch1) != SIG_ERR) e(13);
456433d6423SLionel Sambuc   if (signal(-1, SIG_DFL) != SIG_ERR) e(14);
457433d6423SLionel Sambuc 
458433d6423SLionel Sambuc   /* Verify that caught signals are automatically reset to the default,
459433d6423SLionel Sambuc    * and that further instances of the same signal are not blocked here
460433d6423SLionel Sambuc    * or in the signal handler.
461433d6423SLionel Sambuc    */
462433d6423SLionel Sambuc   if (signal(SIGTERM, catch1) == SIG_ERR) e(15);
463433d6423SLionel Sambuc   switch ((pid = fork())) {
464433d6423SLionel Sambuc       case 0:			/* child */
465433d6423SLionel Sambuc 	errct = 0;
466433d6423SLionel Sambuc 	while (x == 0);
467433d6423SLionel Sambuc 	if (x != 42) e(16);
468433d6423SLionel Sambuc 	if (sigismember((sigset_t *) &glo_vol_set, SIGTERM)) e(17);
469433d6423SLionel Sambuc 	if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &sigset_var) != 0) e(18);
470433d6423SLionel Sambuc 	if (sigismember(&sigset_var, SIGTERM)) e(19);
471433d6423SLionel Sambuc 
472433d6423SLionel Sambuc #if 0
473433d6423SLionel Sambuc /* Use this if you have compiled signal() to have the broken SYSV behaviour. */
474433d6423SLionel Sambuc 	if (signal(SIGTERM, catch1) != SIG_DFL) e(20);
475433d6423SLionel Sambuc #else
476433d6423SLionel Sambuc 	if (signal(SIGTERM, catch1) != catch1) e(20);
477433d6423SLionel Sambuc #endif
478433d6423SLionel Sambuc 	exit(errct == 0 ? 0 : 1);
479433d6423SLionel Sambuc       default:			/* parent */
480433d6423SLionel Sambuc 	sleep(1);
481433d6423SLionel Sambuc 	if (kill(pid, SIGTERM) != 0) e(21);
482433d6423SLionel Sambuc 	wait_for(pid);
483433d6423SLionel Sambuc 	break;
484433d6423SLionel Sambuc       case -1:	e(22);	break;
485433d6423SLionel Sambuc   }
486433d6423SLionel Sambuc }
487433d6423SLionel Sambuc 
488433d6423SLionel Sambuc /*---------------------------------------------------------------------------*/
489433d6423SLionel Sambuc /* Test that the signal handler can be invoked recursively with the
490433d6423SLionel Sambuc * state being properly saved and restored.
491433d6423SLionel Sambuc */
492433d6423SLionel Sambuc 
493433d6423SLionel Sambuc static int y;
494433d6423SLionel Sambuc static int z;
495433d6423SLionel Sambuc 
catch3(signo)496433d6423SLionel Sambuc void catch3(signo)
497433d6423SLionel Sambuc int signo;
498433d6423SLionel Sambuc {
499433d6423SLionel Sambuc   if (z == 1) {			/* catching a nested signal */
500433d6423SLionel Sambuc 	y = 2;
501433d6423SLionel Sambuc 	return;
502433d6423SLionel Sambuc   }
503433d6423SLionel Sambuc   z = 1;
504433d6423SLionel Sambuc   if (kill(getpid(), SIGHUP) != 0) e(1);
505433d6423SLionel Sambuc   while (y != 2);
506433d6423SLionel Sambuc   y = 1;
507433d6423SLionel Sambuc }
508433d6423SLionel Sambuc 
test37d()509433d6423SLionel Sambuc void test37d()
510433d6423SLionel Sambuc {
511433d6423SLionel Sambuc   struct sigaction act;
512433d6423SLionel Sambuc 
513433d6423SLionel Sambuc   subtest = 4;
514433d6423SLionel Sambuc   clearsigstate();
515433d6423SLionel Sambuc   y = 0;
516433d6423SLionel Sambuc   z = 0;
517433d6423SLionel Sambuc 
518433d6423SLionel Sambuc   act.sa_handler = catch3;
519433d6423SLionel Sambuc   sigemptyset(&act.sa_mask);
520433d6423SLionel Sambuc   act.sa_flags = SA_NODEFER;	/* Otherwise, nested occurence of
521433d6423SLionel Sambuc 				 * SIGINT is blocked. */
522433d6423SLionel Sambuc   if (sigaction(SIGHUP, &act, (struct sigaction *) NULL) != 0) e(2);
523433d6423SLionel Sambuc   if (kill(getpid(), SIGHUP) != 0) e(3);
524433d6423SLionel Sambuc   if (y != 1) e(4);
525433d6423SLionel Sambuc }
526433d6423SLionel Sambuc 
527433d6423SLionel Sambuc /*---------------------------------------------------------------------------*/
528433d6423SLionel Sambuc 
529433d6423SLionel Sambuc /* Test that the signal mask in effect for the duration of a signal handler
530433d6423SLionel Sambuc * is as specified in POSIX Section 3, lines 718 -724.  Test that the
531433d6423SLionel Sambuc * previous signal mask is restored when the signal handler returns.
532433d6423SLionel Sambuc */
533433d6423SLionel Sambuc 
catch4(signo)534433d6423SLionel Sambuc void catch4(signo)
535433d6423SLionel Sambuc int signo;
536433d6423SLionel Sambuc {
537433d6423SLionel Sambuc   sigset_t oset;
538433d6423SLionel Sambuc   sigset_t set;
539433d6423SLionel Sambuc 
540433d6423SLionel Sambuc   if (sigemptyset(&set) == -1) e(5001);
541433d6423SLionel Sambuc   if (sigaddset(&set, SIGTERM) == -1) e(5002);
542433d6423SLionel Sambuc   if (sigaddset(&set, SIGHUP) == -1) e(5003);
543433d6423SLionel Sambuc   if (sigaddset(&set, SIGINT) == -1) e(5004);
544433d6423SLionel Sambuc   if (sigaddset(&set, SIGPIPE) == -1) e(5005);
545433d6423SLionel Sambuc   if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &oset) != 0) e(5006);
546433d6423SLionel Sambuc   if (sigmemcmp(&oset, &set, sizeof(set))) e(5007);
547433d6423SLionel Sambuc }
548433d6423SLionel Sambuc 
test37e()549433d6423SLionel Sambuc void test37e()
550433d6423SLionel Sambuc {
551433d6423SLionel Sambuc   struct sigaction act, oact;
552433d6423SLionel Sambuc   sigset_t set, oset;
553433d6423SLionel Sambuc 
554433d6423SLionel Sambuc   subtest = 5;
555433d6423SLionel Sambuc   clearsigstate();
556433d6423SLionel Sambuc 
557433d6423SLionel Sambuc   act.sa_handler = catch4;
558433d6423SLionel Sambuc   sigemptyset(&act.sa_mask);
559433d6423SLionel Sambuc   sigaddset(&act.sa_mask, SIGTERM);
560433d6423SLionel Sambuc   sigaddset(&act.sa_mask, SIGHUP);
561433d6423SLionel Sambuc   act.sa_flags = 0;
562433d6423SLionel Sambuc   if (sigaction(SIGINT, &act, &oact) == -1) e(2);
563433d6423SLionel Sambuc 
564433d6423SLionel Sambuc   if (sigemptyset(&set) == -1) e(3);
565433d6423SLionel Sambuc   if (sigaddset(&set, SIGPIPE) == -1) e(4);
566433d6423SLionel Sambuc   if (sigprocmask(SIG_SETMASK, &set, &oset) == -1) e(5);
567433d6423SLionel Sambuc   if (kill(getpid(), SIGINT) == -1) e(6);
568433d6423SLionel Sambuc   if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &oset) == -1) e(7);
569433d6423SLionel Sambuc   if (sigemptyset(&set) == -1) e(8);
570433d6423SLionel Sambuc   if (sigaddset(&set, SIGPIPE) == -1) e(9);
571433d6423SLionel Sambuc   if (sigmemcmp(&set, &oset, sizeof(set))) e(10);
572433d6423SLionel Sambuc }
573433d6423SLionel Sambuc 
574433d6423SLionel Sambuc /*---------------------------------------------------------------------------*/
575433d6423SLionel Sambuc 
576433d6423SLionel Sambuc /* Test the basic functionality of sigsuspend(2). */
577433d6423SLionel Sambuc 
catch5(signo)578433d6423SLionel Sambuc void catch5(signo)
579433d6423SLionel Sambuc int signo;
580433d6423SLionel Sambuc {
581433d6423SLionel Sambuc   x = 1;
582433d6423SLionel Sambuc }
583433d6423SLionel Sambuc 
test37f()584433d6423SLionel Sambuc void test37f()
585433d6423SLionel Sambuc {
586433d6423SLionel Sambuc   sigset_t set;
587433d6423SLionel Sambuc   int r;
588433d6423SLionel Sambuc   struct sigaction act;
589433d6423SLionel Sambuc   pid_t pid;
590433d6423SLionel Sambuc 
591433d6423SLionel Sambuc   subtest = 6;
592433d6423SLionel Sambuc   clearsigstate();
593433d6423SLionel Sambuc 
594433d6423SLionel Sambuc   switch (pid = fork()) {
595433d6423SLionel Sambuc       case 0:			/* child */
596433d6423SLionel Sambuc 	errct = 0;
597433d6423SLionel Sambuc 	sleep(1);
598433d6423SLionel Sambuc 	if (kill(getppid(), SIGINT) == -1) e(1);
599433d6423SLionel Sambuc 	exit(errct == 0 ? 0 : 1);
600433d6423SLionel Sambuc       case -1:	e(2);	break;
601433d6423SLionel Sambuc       default:			/* parent */
602433d6423SLionel Sambuc 	if (sigemptyset(&act.sa_mask) == -1) e(3);
603433d6423SLionel Sambuc 	act.sa_flags = 0;
604433d6423SLionel Sambuc 	act.sa_handler = catch5;
605433d6423SLionel Sambuc 	if (sigaction(SIGINT, &act, (struct sigaction *) NULL) == -1) e(4);
606433d6423SLionel Sambuc 
607433d6423SLionel Sambuc 	if (sigemptyset(&set) == -1) e(5);
608433d6423SLionel Sambuc 	r = sigsuspend(&set);
609433d6423SLionel Sambuc 
610433d6423SLionel Sambuc 	if (r != -1 || errno != EINTR || x != 1) e(6);
611433d6423SLionel Sambuc 	wait_for(pid);
612433d6423SLionel Sambuc 	break;
613433d6423SLionel Sambuc   }
614433d6423SLionel Sambuc }
615433d6423SLionel Sambuc 
616433d6423SLionel Sambuc /*----------------------------------------------------------------------*/
617433d6423SLionel Sambuc 
618433d6423SLionel Sambuc /* Test that sigsuspend() does block the signals specified in its
619433d6423SLionel Sambuc * argument, and after sigsuspend returns, the previous signal
620433d6423SLionel Sambuc * mask is restored.
621433d6423SLionel Sambuc *
622433d6423SLionel Sambuc * The child sends two signals to the parent SIGINT and then SIGPIPE,
623433d6423SLionel Sambuc * separated by a long delay.  The parent executes sigsuspend() with
624433d6423SLionel Sambuc * SIGINT blocked.  It is expected that the parent's SIGPIPE handler
625433d6423SLionel Sambuc * will be invoked, then sigsuspend will return restoring the
626433d6423SLionel Sambuc * original signal mask, and then the SIGPIPE handler will be
627433d6423SLionel Sambuc * invoked.
628433d6423SLionel Sambuc */
629433d6423SLionel Sambuc 
sigint_handler(signo)630433d6423SLionel Sambuc void sigint_handler(signo)
631433d6423SLionel Sambuc int signo;
632433d6423SLionel Sambuc {
633433d6423SLionel Sambuc   x = 1;
634433d6423SLionel Sambuc   z++;
635433d6423SLionel Sambuc }
636433d6423SLionel Sambuc 
sigpipe_handler(signo)637433d6423SLionel Sambuc void sigpipe_handler(signo)
638433d6423SLionel Sambuc int signo;
639433d6423SLionel Sambuc {
640433d6423SLionel Sambuc   x = 2;
641433d6423SLionel Sambuc   z++;
642433d6423SLionel Sambuc }
643433d6423SLionel Sambuc 
test37g()644433d6423SLionel Sambuc void test37g()
645433d6423SLionel Sambuc {
646433d6423SLionel Sambuc   sigset_t set;
647433d6423SLionel Sambuc   int r;
648433d6423SLionel Sambuc   struct sigaction act;
649433d6423SLionel Sambuc   pid_t pid;
650433d6423SLionel Sambuc 
651433d6423SLionel Sambuc   subtest = 7;
652433d6423SLionel Sambuc   clearsigstate();
653433d6423SLionel Sambuc   x = 0;
654433d6423SLionel Sambuc   z = 0;
655433d6423SLionel Sambuc 
656433d6423SLionel Sambuc   switch (pid = fork()) {
657433d6423SLionel Sambuc       case 0:			/* child */
658433d6423SLionel Sambuc 	errct = 0;
659433d6423SLionel Sambuc 	sleep(1);
660433d6423SLionel Sambuc 	if (kill(getppid(), SIGINT) == -1) e(1);
661433d6423SLionel Sambuc 	sleep(1);
662433d6423SLionel Sambuc 	if (kill(getppid(), SIGPIPE) == -1) e(2);
663433d6423SLionel Sambuc 	exit(errct == 0 ? 0 : 1);
664433d6423SLionel Sambuc       case -1:	e(3);	break;
665433d6423SLionel Sambuc       default:			/* parent */
666433d6423SLionel Sambuc 	if (sigemptyset(&act.sa_mask) == -1) e(3);
667433d6423SLionel Sambuc 	act.sa_flags = 0;
668433d6423SLionel Sambuc 	act.sa_handler = sigint_handler;
669433d6423SLionel Sambuc 	if (sigaction(SIGINT, &act, (struct sigaction *) NULL) == -1) e(4);
670433d6423SLionel Sambuc 
671433d6423SLionel Sambuc 	act.sa_handler = sigpipe_handler;
672433d6423SLionel Sambuc 	if (sigaction(SIGPIPE, &act, (struct sigaction *) NULL) == -1) e(5);
673433d6423SLionel Sambuc 
674433d6423SLionel Sambuc 	if (sigemptyset(&set) == -1) e(6);
675433d6423SLionel Sambuc 	if (sigaddset(&set, SIGINT) == -1) e(7);
676433d6423SLionel Sambuc 	r = sigsuspend(&set);
677433d6423SLionel Sambuc 	if (r != -1) e(8);
678433d6423SLionel Sambuc 	if (errno != EINTR) e(9);
679433d6423SLionel Sambuc 	if (z != 2) e(10);
680433d6423SLionel Sambuc 	if (x != 1) e(11);
681433d6423SLionel Sambuc 	wait_for(pid);
682433d6423SLionel Sambuc 	break;
683433d6423SLionel Sambuc   }
684433d6423SLionel Sambuc }
685433d6423SLionel Sambuc 
686433d6423SLionel Sambuc /*--------------------------------------------------------------------------*/
687433d6423SLionel Sambuc 
688433d6423SLionel Sambuc /* Test that sigsuspend() does block the signals specified in its
689433d6423SLionel Sambuc * argument, and after sigsuspend returns, the previous signal
690433d6423SLionel Sambuc * mask is restored.
691433d6423SLionel Sambuc *
692433d6423SLionel Sambuc * The child sends three signals to the parent: SIGHUP, then SIGPIPE,
693433d6423SLionel Sambuc * and then SIGTERM, separated by a long delay.  The parent executes
694433d6423SLionel Sambuc * sigsuspend() with SIGHUP and SIGPIPE blocked.  It is expected that
695433d6423SLionel Sambuc * the parent's SIGTERM handler will be invoked first, then sigsuspend()
696433d6423SLionel Sambuc * will return restoring the original signal mask, and then the other
697433d6423SLionel Sambuc * two handlers will be invoked.
698433d6423SLionel Sambuc */
699433d6423SLionel Sambuc 
sighup8(signo)700433d6423SLionel Sambuc void sighup8(signo)
701433d6423SLionel Sambuc int signo;
702433d6423SLionel Sambuc {
703433d6423SLionel Sambuc   x = 1;
704433d6423SLionel Sambuc   z++;
705433d6423SLionel Sambuc }
706433d6423SLionel Sambuc 
sigpip8(signo)707433d6423SLionel Sambuc void sigpip8(signo)
708433d6423SLionel Sambuc int signo;
709433d6423SLionel Sambuc {
710433d6423SLionel Sambuc   x = 1;
711433d6423SLionel Sambuc   z++;
712433d6423SLionel Sambuc }
713433d6423SLionel Sambuc 
sigter8(signo)714433d6423SLionel Sambuc void sigter8(signo)
715433d6423SLionel Sambuc int signo;
716433d6423SLionel Sambuc {
717433d6423SLionel Sambuc   x = 2;
718433d6423SLionel Sambuc   z++;
719433d6423SLionel Sambuc }
720433d6423SLionel Sambuc 
test37h()721433d6423SLionel Sambuc void test37h()
722433d6423SLionel Sambuc {
723433d6423SLionel Sambuc   sigset_t set;
724433d6423SLionel Sambuc   int r;
725433d6423SLionel Sambuc   struct sigaction act;
726433d6423SLionel Sambuc   pid_t pid;
727433d6423SLionel Sambuc 
728433d6423SLionel Sambuc   subtest = 8;
729433d6423SLionel Sambuc   clearsigstate();
730433d6423SLionel Sambuc   x = 0;
731433d6423SLionel Sambuc   z = 0;
732433d6423SLionel Sambuc 
733433d6423SLionel Sambuc   switch (pid = fork()) {
734433d6423SLionel Sambuc       case 0:			/* child */
735433d6423SLionel Sambuc 	errct = 0;
736433d6423SLionel Sambuc 	sleep(1);
737433d6423SLionel Sambuc 	if (kill(getppid(), SIGHUP) == -1) e(1);
738433d6423SLionel Sambuc 	sleep(1);
739433d6423SLionel Sambuc 	if (kill(getppid(), SIGPIPE) == -1) e(2);
740433d6423SLionel Sambuc 	sleep(1);
741433d6423SLionel Sambuc 	if (kill(getppid(), SIGTERM) == -1) e(3);
742433d6423SLionel Sambuc 	exit(errct == 0 ? 0 : 1);
743433d6423SLionel Sambuc       case -1:	e(5);	break;
744433d6423SLionel Sambuc       default:			/* parent */
745433d6423SLionel Sambuc 	if (sigemptyset(&act.sa_mask) == -1) e(6);
746433d6423SLionel Sambuc 	act.sa_flags = 0;
747433d6423SLionel Sambuc 	act.sa_handler = sighup8;
748433d6423SLionel Sambuc 	if (sigaction(SIGHUP, &act, (struct sigaction *) NULL) == -1) e(7);
749433d6423SLionel Sambuc 
750433d6423SLionel Sambuc 	act.sa_handler = sigpip8;
751433d6423SLionel Sambuc 	if (sigaction(SIGPIPE, &act, (struct sigaction *) NULL) == -1) e(8);
752433d6423SLionel Sambuc 
753433d6423SLionel Sambuc 	act.sa_handler = sigter8;
754433d6423SLionel Sambuc 	if (sigaction(SIGTERM, &act, (struct sigaction *) NULL) == -1) e(9);
755433d6423SLionel Sambuc 
756433d6423SLionel Sambuc 	if (sigemptyset(&set) == -1) e(10);
757433d6423SLionel Sambuc 	if (sigaddset(&set, SIGHUP) == -1) e(11);
758433d6423SLionel Sambuc 	if (sigaddset(&set, SIGPIPE) == -1) e(12);
759433d6423SLionel Sambuc 	r = sigsuspend(&set);
760433d6423SLionel Sambuc 	if (r != -1) e(13);
761433d6423SLionel Sambuc 	if (errno != EINTR) e(14);
762433d6423SLionel Sambuc 	if (z != 3) e(15);
763433d6423SLionel Sambuc 	if (x != 1) e(16);
764433d6423SLionel Sambuc 	wait_for(pid);
765433d6423SLionel Sambuc 	break;
766433d6423SLionel Sambuc   }
767433d6423SLionel Sambuc }
768433d6423SLionel Sambuc 
769433d6423SLionel Sambuc /*--------------------------------------------------------------------------*/
770433d6423SLionel Sambuc 
771433d6423SLionel Sambuc /* Block SIGHUP and SIGTERM with sigprocmask(), send ourself SIGHUP
772433d6423SLionel Sambuc * and SIGTERM, unblock these signals with sigprocmask, and verify
773433d6423SLionel Sambuc * that these signals are delivered.
774433d6423SLionel Sambuc */
775433d6423SLionel Sambuc 
sighup9(signo)776433d6423SLionel Sambuc void sighup9(signo)
777433d6423SLionel Sambuc int signo;
778433d6423SLionel Sambuc {
779433d6423SLionel Sambuc   y++;
780433d6423SLionel Sambuc }
781433d6423SLionel Sambuc 
sigter9(signo)782433d6423SLionel Sambuc void sigter9(signo)
783433d6423SLionel Sambuc int signo;
784433d6423SLionel Sambuc {
785433d6423SLionel Sambuc   z++;
786433d6423SLionel Sambuc }
787433d6423SLionel Sambuc 
test37i()788433d6423SLionel Sambuc void test37i()
789433d6423SLionel Sambuc {
790433d6423SLionel Sambuc   sigset_t set;
791433d6423SLionel Sambuc   struct sigaction act;
792433d6423SLionel Sambuc 
793433d6423SLionel Sambuc   subtest = 9;
794433d6423SLionel Sambuc   clearsigstate();
795433d6423SLionel Sambuc   y = 0;
796433d6423SLionel Sambuc   z = 0;
797433d6423SLionel Sambuc 
798433d6423SLionel Sambuc   if (sigemptyset(&act.sa_mask) == -1) e(1);
799433d6423SLionel Sambuc   act.sa_flags = 0;
800433d6423SLionel Sambuc 
801433d6423SLionel Sambuc   act.sa_handler = sighup9;
802433d6423SLionel Sambuc   if (sigaction(SIGHUP, &act, (struct sigaction *) NULL) == -1) e(2);
803433d6423SLionel Sambuc 
804433d6423SLionel Sambuc   act.sa_handler = sigter9;
805433d6423SLionel Sambuc   if (sigaction(SIGTERM, &act, (struct sigaction *) NULL) == -1) e(3);
806433d6423SLionel Sambuc 
807433d6423SLionel Sambuc   if (sigemptyset(&set) == -1) e(4);
808433d6423SLionel Sambuc   if (sigaddset(&set, SIGTERM) == -1) e(5);
809433d6423SLionel Sambuc   if (sigaddset(&set, SIGHUP) == -1) e(6);
810433d6423SLionel Sambuc   if (sigprocmask(SIG_SETMASK, &set, (sigset_t *)NULL) == -1) e(7);
811433d6423SLionel Sambuc 
812433d6423SLionel Sambuc   if (kill(getpid(), SIGHUP) == -1) e(8);
813433d6423SLionel Sambuc   if (kill(getpid(), SIGTERM) == -1) e(9);
814433d6423SLionel Sambuc   if (y != 0) e(10);
815433d6423SLionel Sambuc   if (z != 0) e(11);
816433d6423SLionel Sambuc 
817433d6423SLionel Sambuc   if (sigemptyset(&set) == -1) e(12);
818433d6423SLionel Sambuc   if (sigprocmask(SIG_SETMASK, &set, (sigset_t *)NULL) == -1) e(12);
819433d6423SLionel Sambuc   if (y != 1) e(13);
820433d6423SLionel Sambuc   if (z != 1) e(14);
821433d6423SLionel Sambuc }
822433d6423SLionel Sambuc 
823433d6423SLionel Sambuc /*---------------------------------------------------------------------------*/
824433d6423SLionel Sambuc 
825433d6423SLionel Sambuc /* Block SIGINT and then send this signal to ourself.
826433d6423SLionel Sambuc *
827433d6423SLionel Sambuc * Install signal handlers for SIGALRM and SIGINT.
828433d6423SLionel Sambuc *
829433d6423SLionel Sambuc * Set an alarm for 6 seconds, then sleep for 7.
830433d6423SLionel Sambuc *
831433d6423SLionel Sambuc * The SIGALRM should interrupt the sleep, but the SIGINT
832433d6423SLionel Sambuc * should remain pending.
833433d6423SLionel Sambuc */
834433d6423SLionel Sambuc 
sighup10(signo)835433d6423SLionel Sambuc void sighup10(signo)
836433d6423SLionel Sambuc int signo;
837433d6423SLionel Sambuc {
838433d6423SLionel Sambuc   y++;
839433d6423SLionel Sambuc }
840433d6423SLionel Sambuc 
sigalrm_handler10(signo)841433d6423SLionel Sambuc void sigalrm_handler10(signo)
842433d6423SLionel Sambuc int signo;
843433d6423SLionel Sambuc {
844433d6423SLionel Sambuc   z++;
845433d6423SLionel Sambuc }
846433d6423SLionel Sambuc 
test37j()847433d6423SLionel Sambuc void test37j()
848433d6423SLionel Sambuc {
849433d6423SLionel Sambuc   sigset_t set, set2;
850433d6423SLionel Sambuc   struct sigaction act;
851433d6423SLionel Sambuc 
852433d6423SLionel Sambuc   subtest = 10;
853433d6423SLionel Sambuc   clearsigstate();
854433d6423SLionel Sambuc   y = 0;
855433d6423SLionel Sambuc   z = 0;
856433d6423SLionel Sambuc 
857433d6423SLionel Sambuc   if (sigemptyset(&act.sa_mask) == -1) e(1);
858433d6423SLionel Sambuc   act.sa_flags = 0;
859433d6423SLionel Sambuc 
860433d6423SLionel Sambuc   act.sa_handler = sighup10;
861433d6423SLionel Sambuc   if (sigaction(SIGHUP, &act, (struct sigaction *) NULL) == -1) e(2);
862433d6423SLionel Sambuc 
863433d6423SLionel Sambuc   act.sa_handler = sigalrm_handler10;
864433d6423SLionel Sambuc   if (sigaction(SIGALRM, &act, (struct sigaction *) NULL) == -1) e(3);
865433d6423SLionel Sambuc 
866433d6423SLionel Sambuc   if (sigemptyset(&set) == -1) e(4);
867433d6423SLionel Sambuc   if (sigaddset(&set, SIGHUP) == -1) e(5);
868433d6423SLionel Sambuc   if (sigprocmask(SIG_SETMASK, &set, (sigset_t *)NULL) == -1) e(6);
869433d6423SLionel Sambuc 
870433d6423SLionel Sambuc   if (kill(getpid(), SIGHUP) == -1) e(7);
871433d6423SLionel Sambuc   if (sigpending(&set) == -1) e(8);
872433d6423SLionel Sambuc   if (sigemptyset(&set2) == -1) e(9);
873433d6423SLionel Sambuc   if (sigaddset(&set2, SIGHUP) == -1) e(10);
874433d6423SLionel Sambuc   if (sigmemcmp(&set2, &set, sizeof(set))) e(11);
875433d6423SLionel Sambuc   alarm(6);
876433d6423SLionel Sambuc   sleep(7);
877433d6423SLionel Sambuc   if (sigpending(&set) == -1) e(12);
878433d6423SLionel Sambuc   if (sigmemcmp(&set, &set2, sizeof(set))) e(13);
879433d6423SLionel Sambuc   if (y != 0) e(14);
880433d6423SLionel Sambuc   if (z != 1) e(15);
881433d6423SLionel Sambuc }
882433d6423SLionel Sambuc 
883433d6423SLionel Sambuc /*--------------------------------------------------------------------------*/
884433d6423SLionel Sambuc 
test37k()885433d6423SLionel Sambuc void test37k()
886433d6423SLionel Sambuc {
887433d6423SLionel Sambuc   subtest = 11;
888433d6423SLionel Sambuc }
test37l()889433d6423SLionel Sambuc void test37l()
890433d6423SLionel Sambuc {
891433d6423SLionel Sambuc   subtest = 12;
892433d6423SLionel Sambuc }
893433d6423SLionel Sambuc 
894433d6423SLionel Sambuc /*---------------------------------------------------------------------------*/
895433d6423SLionel Sambuc 
896433d6423SLionel Sambuc /* Basic test for setjmp/longjmp.  This includes testing that the
897433d6423SLionel Sambuc * signal mask is properly restored.
898433d6423SLionel Sambuc */
899433d6423SLionel Sambuc 
900433d6423SLionel Sambuc #define TEST_SETJMP(_name, _subtest, _type, _setjmp, _longjmp, _save)	\
901433d6423SLionel Sambuc void _name(void)							\
902433d6423SLionel Sambuc {									\
903433d6423SLionel Sambuc   _type jb;								\
904433d6423SLionel Sambuc   sigset_t ss, ss2, ss_orig;						\
905433d6423SLionel Sambuc 									\
906433d6423SLionel Sambuc   subtest = _subtest;							\
907433d6423SLionel Sambuc   clearsigstate();							\
908433d6423SLionel Sambuc 									\
909433d6423SLionel Sambuc   sigemptyset(&ss); sigemptyset(&ss2);					\
910433d6423SLionel Sambuc   sigaddset(&ss,   2); sigaddset(&ss,   4); sigaddset(&ss,   5);	\
911433d6423SLionel Sambuc   sigaddset(&ss2, 20); sigaddset(&ss2, 22); sigaddset(&ss2, 65);	\
912433d6423SLionel Sambuc   memcpy(&ss_orig, &ss, sizeof(ss));					\
913433d6423SLionel Sambuc   if (sigprocmask(SIG_SETMASK, &ss, (sigset_t *)NULL) == -1) e(1);	\
914433d6423SLionel Sambuc   if (_setjmp) {							\
915433d6423SLionel Sambuc 	sigset_t ssexp;							\
916433d6423SLionel Sambuc 	if (sigprocmask(SIG_BLOCK, (sigset_t *)NULL, &ss) == -1) e(2);	\
917433d6423SLionel Sambuc 	ssexp = _save ? ss_orig : ss2;					\
918433d6423SLionel Sambuc 	sigdelset(&ssexp, SIGKILL);					\
919433d6423SLionel Sambuc 	if (sigmemcmp(&ss, &ssexp, sizeof(ss))) e(388);			\
920433d6423SLionel Sambuc 	return;								\
921433d6423SLionel Sambuc   }									\
922433d6423SLionel Sambuc   ss = ss2;								\
923433d6423SLionel Sambuc   if (sigprocmask(SIG_SETMASK, &ss, (sigset_t *)NULL) == -1) e(4);	\
924433d6423SLionel Sambuc   _longjmp;								\
925433d6423SLionel Sambuc }
926433d6423SLionel Sambuc 
927433d6423SLionel Sambuc TEST_SETJMP(test37m, 13, jmp_buf,    setjmp(jb),       longjmp(jb, 1),    1)
928433d6423SLionel Sambuc TEST_SETJMP(test37p, 16, sigjmp_buf, sigsetjmp(jb, 0), siglongjmp(jb, 1), 0)
929433d6423SLionel Sambuc TEST_SETJMP(test37q, 17, sigjmp_buf, sigsetjmp(jb, 1), siglongjmp(jb, 1), 1)
930433d6423SLionel Sambuc 
longjerr()931433d6423SLionel Sambuc void longjerr()
932433d6423SLionel Sambuc {
933433d6423SLionel Sambuc   e(5);
934433d6423SLionel Sambuc }
935433d6423SLionel Sambuc 
936433d6423SLionel Sambuc /*--------------------------------------------------------------------------*/
937433d6423SLionel Sambuc 
938433d6423SLionel Sambuc /* Test for setjmp/longjmp.
939433d6423SLionel Sambuc *
940433d6423SLionel Sambuc * Catch a signal.  While in signal handler do setjmp/longjmp.
941433d6423SLionel Sambuc */
942433d6423SLionel Sambuc 
catch14(signo,code,scp)943433d6423SLionel Sambuc void catch14(signo, code, scp)
944433d6423SLionel Sambuc int signo;
945433d6423SLionel Sambuc int code;
946433d6423SLionel Sambuc struct sigcontext *scp;
947433d6423SLionel Sambuc {
948433d6423SLionel Sambuc   jmp_buf jb;
949433d6423SLionel Sambuc 
950433d6423SLionel Sambuc   if (setjmp(jb)) {
951433d6423SLionel Sambuc 	x++;
952433d6423SLionel Sambuc 	sigreturn(scp);
953433d6423SLionel Sambuc 	e(1);
954433d6423SLionel Sambuc   }
955433d6423SLionel Sambuc   y++;
956433d6423SLionel Sambuc   longjmp(jb, 1);
957433d6423SLionel Sambuc   e(2);
958433d6423SLionel Sambuc }
959433d6423SLionel Sambuc 
test37n()960433d6423SLionel Sambuc void test37n()
961433d6423SLionel Sambuc {
962433d6423SLionel Sambuc   struct sigaction act;
963433d6423SLionel Sambuc   typedef void(*sighandler_t) (int sig);
964433d6423SLionel Sambuc 
965433d6423SLionel Sambuc   subtest = 14;
966433d6423SLionel Sambuc   clearsigstate();
967433d6423SLionel Sambuc   x = 0;
968433d6423SLionel Sambuc   y = 0;
969433d6423SLionel Sambuc 
970433d6423SLionel Sambuc   act.sa_flags = 0;
971433d6423SLionel Sambuc   sigemptyset(&act.sa_mask);
972433d6423SLionel Sambuc   act.sa_handler = (sighandler_t) catch14;	/* fudge */
973433d6423SLionel Sambuc   if (sigaction(SIGSEGV, &act, (struct sigaction *) NULL) == -1) e(3);
974433d6423SLionel Sambuc   if (kill(getpid(), SIGSEGV) == -1) e(4);
975433d6423SLionel Sambuc 
976433d6423SLionel Sambuc   if (x != 1) e(5);
977433d6423SLionel Sambuc   if (y != 1) e(6);
978433d6423SLionel Sambuc }
979433d6423SLionel Sambuc 
980433d6423SLionel Sambuc /*---------------------------------------------------------------------------*/
981433d6423SLionel Sambuc 
982433d6423SLionel Sambuc /* Test for setjmp/longjmp.
983433d6423SLionel Sambuc  *
984433d6423SLionel Sambuc  * Catch a signal.  Longjmp out of signal handler.
985433d6423SLionel Sambuc  */
986433d6423SLionel Sambuc jmp_buf glo_jb;
987433d6423SLionel Sambuc 
catch15(signo)988433d6423SLionel Sambuc void catch15(signo)
989433d6423SLionel Sambuc int signo;
990433d6423SLionel Sambuc {
991433d6423SLionel Sambuc   z++;
992433d6423SLionel Sambuc   longjmp(glo_jb, 7);
993433d6423SLionel Sambuc   e(1);
994433d6423SLionel Sambuc 
995433d6423SLionel Sambuc }
996433d6423SLionel Sambuc 
test37o()997433d6423SLionel Sambuc void test37o()
998433d6423SLionel Sambuc {
999433d6423SLionel Sambuc   struct sigaction act;
1000433d6423SLionel Sambuc   int k;
1001433d6423SLionel Sambuc 
1002433d6423SLionel Sambuc   subtest = 15;
1003433d6423SLionel Sambuc   clearsigstate();
1004433d6423SLionel Sambuc   z = 0;
1005433d6423SLionel Sambuc 
1006433d6423SLionel Sambuc   act.sa_flags = 0;
1007433d6423SLionel Sambuc   sigemptyset(&act.sa_mask);
1008433d6423SLionel Sambuc   act.sa_handler = catch15;
1009433d6423SLionel Sambuc   if (sigaction(SIGALRM, &act, (struct sigaction *) NULL) == -1) e(2);
1010433d6423SLionel Sambuc 
1011433d6423SLionel Sambuc   if ((k = setjmp(glo_jb))) {
1012433d6423SLionel Sambuc 	if (z != 1) e(399);
1013433d6423SLionel Sambuc 	if (k != 7) e(4);
1014433d6423SLionel Sambuc 	return;
1015433d6423SLionel Sambuc   }
1016433d6423SLionel Sambuc   if (kill(getpid(), SIGALRM) == -1) e(5);
1017433d6423SLionel Sambuc }
1018433d6423SLionel Sambuc 
clearsigstate()1019433d6423SLionel Sambuc void clearsigstate()
1020433d6423SLionel Sambuc {
1021433d6423SLionel Sambuc   int i;
1022433d6423SLionel Sambuc   sigset_t sigset_var;
1023433d6423SLionel Sambuc 
1024433d6423SLionel Sambuc   /* Clear the signal state. */
1025433d6423SLionel Sambuc   for (i = 1; i < _NSIG; i++) signal(i, SIG_IGN);
1026433d6423SLionel Sambuc   for (i = 1; i < _NSIG; i++) signal(i, SIG_DFL);
1027433d6423SLionel Sambuc   sigfillset(&sigset_var);
1028433d6423SLionel Sambuc   sigprocmask(SIG_UNBLOCK, &sigset_var, (sigset_t *)NULL);
1029433d6423SLionel Sambuc }
1030433d6423SLionel Sambuc 
wait_for(pid)1031433d6423SLionel Sambuc void wait_for(pid)
1032433d6423SLionel Sambuc pid_t pid;
1033433d6423SLionel Sambuc {
1034433d6423SLionel Sambuc /* Expect exactly one child, and that it exits with 0. */
1035433d6423SLionel Sambuc 
1036433d6423SLionel Sambuc   int r;
1037433d6423SLionel Sambuc   int status;
1038433d6423SLionel Sambuc 
1039433d6423SLionel Sambuc   errno = 0;
1040433d6423SLionel Sambuc   while (1) {
1041433d6423SLionel Sambuc 	errno = 0;
1042433d6423SLionel Sambuc 	r = wait(&status);
1043433d6423SLionel Sambuc 	if (r == pid) {
1044433d6423SLionel Sambuc 		errno = 0;
1045433d6423SLionel Sambuc 		if (status != 0) e(90);
1046433d6423SLionel Sambuc 		return;
1047433d6423SLionel Sambuc 	}
1048433d6423SLionel Sambuc 	if (r < 0) {
1049433d6423SLionel Sambuc 		e(91);
1050433d6423SLionel Sambuc 		return;
1051433d6423SLionel Sambuc 	}
1052433d6423SLionel Sambuc 	e(92);
1053433d6423SLionel Sambuc   }
1054433d6423SLionel Sambuc }
1055433d6423SLionel Sambuc 
1056