1824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm/* libunwind - a platform-independent unwind library
2824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm   Copyright (C) 2003 Hewlett-Packard Co
3824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
5824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmPermission is hereby granted, free of charge, to any person obtaining
6824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidma copy of this software and associated documentation files (the
7824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm"Software"), to deal in the Software without restriction, including
8824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmwithout limitation the rights to use, copy, modify, merge, publish,
9824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmdistribute, sublicense, and/or sell copies of the Software, and to
10824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmpermit persons to whom the Software is furnished to do so, subject to
11824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmthe following conditions:
12824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
13824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmThe above copyright notice and this permission notice shall be
14824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmincluded in all copies or substantial portions of the Software.
15824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
16824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
23824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
24824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm/* The setjmp()/longjmp(), sigsetjmp()/siglongjmp().  */
25824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
266b55e0ab51eee7dbea679fda2b37ecf61f0025e5Tommi Rantala#include "compiler.h"
276b55e0ab51eee7dbea679fda2b37ecf61f0025e5Tommi Rantala
28824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm#include <setjmp.h>
29824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm#include <signal.h>
30824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm#include <stdio.h>
31824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm#include <stdlib.h>
32824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm#include <string.h>
33824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm#include <unistd.h>
34824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
35824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmint nerrors;
36824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmint verbose;
37824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
38824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmstatic jmp_buf jbuf;
39824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmstatic sigjmp_buf sigjbuf;
40824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmstatic sigset_t sigset4;
41824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
42824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmvoid
43824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmraise_longjmp (jmp_buf jbuf, int i, int n)
44824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm{
45824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  while (i < n)
46824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    raise_longjmp (jbuf, i + 1, n);
47824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
48824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  longjmp (jbuf, n);
49824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm}
50824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
51824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmvoid
52824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmtest_setjmp (void)
53824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm{
54824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  volatile int i;
55824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  jmp_buf jbuf;
56824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  int ret;
57824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
58824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  for (i = 0; i < 10; ++i)
59824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    {
60824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      if ((ret = setjmp (jbuf)))
61824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	{
62824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	  if (verbose)
63824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	    printf ("%s: secondary setjmp () return, ret=%d\n",
64824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm		    __FUNCTION__, ret);
65824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	  if (ret != i + 1)
66824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	    {
67824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	      fprintf (stderr, "%s: setjmp() returned %d, expected %d\n",
68824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm		       __FUNCTION__, ret, i + 1);
69824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	      ++nerrors;
70824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	    }
71824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	  continue;
72824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	}
73824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      if (verbose)
74824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	printf ("%s.%d: done with setjmp(); calling children\n",
75824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm		__FUNCTION__, i + 1);
76824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
77824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      raise_longjmp (jbuf, 0, i + 1);
78824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
791c5c60b8ad9fa2094fb03aa211d9717dd8b30f05hp.com!davidm      fprintf (stderr, "%s: raise_longjmp() returned unexpectedly\n",
80824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	       __FUNCTION__);
81824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      ++nerrors;
82824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    }
83824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm}
84824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
85824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
86824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmvoid
87824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmraise_siglongjmp (sigjmp_buf jbuf, int i, int n)
88824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm{
89824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  while (i < n)
90824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    raise_siglongjmp (jbuf, i + 1, n);
91824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
92824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  siglongjmp (jbuf, n);
93824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm}
94824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
95824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmvoid
96824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmtest_sigsetjmp (void)
97824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm{
98824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  sigjmp_buf jbuf;
995adfead33ce720c41f0ffa9f0f6222794343f67cmostang.com!davidm  volatile int i;
1005adfead33ce720c41f0ffa9f0f6222794343f67cmostang.com!davidm  int ret;
101824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
102824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  for (i = 0; i < 10; ++i)
103824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    {
104824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      if ((ret = sigsetjmp (jbuf, 1)))
105824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	{
106824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	  if (verbose)
107824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	    printf ("%s: secondary sigsetjmp () return, ret=%d\n",
108824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm		    __FUNCTION__, ret);
109824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	  if (ret != i + 1)
110824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	    {
111824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	      fprintf (stderr, "%s: sigsetjmp() returned %d, expected %d\n",
112824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm		       __FUNCTION__, ret, i + 1);
113824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	      ++nerrors;
114824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	    }
115824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	  continue;
116824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	}
117824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      if (verbose)
118824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	printf ("%s.%d: done with sigsetjmp(); calling children\n",
119824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm		__FUNCTION__, i + 1);
120824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
121824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      raise_siglongjmp (jbuf, 0, i + 1);
122824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
1231c5c60b8ad9fa2094fb03aa211d9717dd8b30f05hp.com!davidm      fprintf (stderr, "%s: raise_siglongjmp() returned unexpectedly\n",
124824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	       __FUNCTION__);
125824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      ++nerrors;
126824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    }
127824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm}
128824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
129824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmvoid
130824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmsighandler (int signal)
131824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm{
132824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  if (verbose)
133824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    printf ("%s: got signal %d\n", __FUNCTION__, signal);
134824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
135824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset4);
1361c5c60b8ad9fa2094fb03aa211d9717dd8b30f05hp.com!davidm  if (verbose)
1371c5c60b8ad9fa2094fb03aa211d9717dd8b30f05hp.com!davidm    printf ("%s: back from sigprocmask\n", __FUNCTION__);
1381c5c60b8ad9fa2094fb03aa211d9717dd8b30f05hp.com!davidm
139824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  siglongjmp (sigjbuf, 1);
1401c5c60b8ad9fa2094fb03aa211d9717dd8b30f05hp.com!davidm  printf ("%s: siglongjmp() returned unexpectedly!\n", __FUNCTION__);
141824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm}
142824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
143824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidmint
1446b55e0ab51eee7dbea679fda2b37ecf61f0025e5Tommi Rantalamain (int argc, char **argv UNUSED)
145824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm{
146824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  volatile sigset_t sigset1, sigset2, sigset3;
147824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  volatile struct sigaction act;
148824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
149824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  if (argc > 1)
150824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    verbose = 1;
151824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
152824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  sigemptyset ((sigset_t *) &sigset1);
153824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  sigaddset ((sigset_t *) &sigset1, SIGUSR1);
154824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  sigemptyset ((sigset_t *) &sigset2);
155824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  sigaddset ((sigset_t *) &sigset2, SIGUSR2);
156824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
157824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  memset ((void *) &act, 0, sizeof (act));
158824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  act.sa_handler = sighandler;
159824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  sigaction (SIGTERM, (struct sigaction *) &act, NULL);
160824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
161824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  test_setjmp ();
162824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  test_sigsetjmp ();
163824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
164824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  /* _setjmp() MUST NOT change signal mask: */
165824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  sigprocmask (SIG_SETMASK, (sigset_t *) &sigset1, NULL);
166824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  if (_setjmp (jbuf))
167824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    {
168824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      sigemptyset ((sigset_t *) &sigset3);
169824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3);
170824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset2,
171824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm		  sizeof (sigset_t)) != 0)
172824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	{
173824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	  fprintf (stderr, "FAILURE: _longjmp() manipulated signal mask!\n");
174824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	  ++nerrors;
175824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	}
176824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      else if (verbose)
177824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	printf ("OK: _longjmp() seems not to change signal mask\n");
178824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    }
179824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  else
180824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    {
181824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      sigprocmask (SIG_SETMASK, (sigset_t *) &sigset2, NULL);
182824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      _longjmp (jbuf, 1);
183824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    }
184824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
185824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  /* sigsetjmp(jbuf, 1) MUST preserve signal mask: */
186824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  sigprocmask (SIG_SETMASK, (sigset_t *) &sigset1, NULL);
187824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  if (sigsetjmp (sigjbuf, 1))
188824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    {
189824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      sigemptyset ((sigset_t *) &sigset3);
190824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3);
191824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset1,
192824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm		  sizeof (sigset_t)) != 0)
193824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	{
194824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	  fprintf (stderr,
195824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm		   "FAILURE: siglongjmp() didn't restore signal mask!\n");
196824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	  ++nerrors;
197824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	}
198824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      else if (verbose)
199824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	printf ("OK: siglongjmp() restores signal mask when asked to\n");
200824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    }
201824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  else
202824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    {
203824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      sigprocmask (SIG_SETMASK, (sigset_t *) &sigset2, NULL);
204824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      siglongjmp (sigjbuf, 1);
205824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    }
206824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
207824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  /* sigsetjmp(jbuf, 0) MUST NOT preserve signal mask: */
208824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  sigprocmask (SIG_SETMASK, (sigset_t *) &sigset1, NULL);
209824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  if (sigsetjmp (sigjbuf, 0))
210824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    {
211824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      sigemptyset ((sigset_t *) &sigset3);
212824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3);
213824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset2,
214824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm		  sizeof (sigset_t)) != 0)
215824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	{
216824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	  fprintf (stderr,
217824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm		   "FAILURE: siglongjmp() changed signal mask!\n");
218824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	  ++nerrors;
219824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	}
220824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      else if (verbose)
2211c5c60b8ad9fa2094fb03aa211d9717dd8b30f05hp.com!davidm	printf ("OK: siglongjmp() leaves signal mask alone when asked to\n");
222824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    }
223824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  else
224824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    {
225824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      sigprocmask (SIG_SETMASK, (sigset_t *) &sigset2, NULL);
226824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      siglongjmp (sigjbuf, 1);
227824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    }
228824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
229824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  /* sigsetjmp(jbuf, 1) MUST preserve signal mask: */
230824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  sigprocmask (SIG_SETMASK, (sigset_t *) &sigset1, NULL);
231824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  if (sigsetjmp (sigjbuf, 1))
232824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    {
233824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      sigemptyset ((sigset_t *) &sigset3);
234824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3);
235824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset1,
236824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm		  sizeof (sigset_t)) != 0)
237824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	{
238824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	  fprintf (stderr,
239824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm		   "FAILURE: siglongjmp() didn't restore signal mask!\n");
240824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	  ++nerrors;
241824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	}
242824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      else if (verbose)
243824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	printf ("OK: siglongjmp() restores signal mask when asked to\n");
244824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    }
245824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  else
246824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    {
247824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      sigprocmask (SIG_SETMASK, (sigset_t *) &sigset2, NULL);
248824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      kill (getpid (), SIGTERM);
249824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      fprintf (stderr, "FAILURE: unexpected return from kill()\n");
250824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      ++nerrors;
251824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    }
252824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
253824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  /* sigsetjmp(jbuf, 0) MUST NOT preserve signal mask: */
254824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  sigprocmask (SIG_SETMASK, (sigset_t *) &sigset1, NULL);
255824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  if (sigsetjmp (sigjbuf, 0))
256824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    {
257824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      sigemptyset ((sigset_t *) &sigset3);
258824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3);
259824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset4,
260824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm		  sizeof (sigset_t)) != 0)
261824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	{
262824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	  fprintf (stderr,
263824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm		   "FAILURE: siglongjmp() changed signal mask!\n");
264824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	  ++nerrors;
265824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm	}
266824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      else if (verbose)
2671c5c60b8ad9fa2094fb03aa211d9717dd8b30f05hp.com!davidm	printf ("OK: siglongjmp() leaves signal mask alone when asked to\n");
268824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    }
269824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  else
270824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    {
271824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      sigprocmask (SIG_SETMASK, (sigset_t *) &sigset2, NULL);
272824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      kill (getpid (), SIGTERM);
273824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      fprintf (stderr, "FAILURE: unexpected return from kill()\n");
274824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      ++nerrors;
275824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    }
276824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm
277824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  if (nerrors > 0)
278824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    {
279824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      fprintf (stderr, "FAILURE: detected %d failures\n", nerrors);
280824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm      exit (-1);
281824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    }
282824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  if (verbose)
283824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm    printf ("SUCCESS\n");
284824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm  return 0;
285824d6619b500a86ff2fc680268357f0215d59b0cmostang.com!davidm}
286