1 /* libunwind - a platform-independent unwind library
2 Copyright (C) 2003 Hewlett-Packard Co
3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
5 Permission is hereby granted, free of charge, to any person obtaining
6 a copy of this software and associated documentation files (the
7 "Software"), to deal in the Software without restriction, including
8 without limitation the rights to use, copy, modify, merge, publish,
9 distribute, sublicense, and/or sell copies of the Software, and to
10 permit persons to whom the Software is furnished to do so, subject to
11 the following conditions:
13 The above copyright notice and this permission notice shall be
14 included in all copies or substantial portions of the Software.
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
24 /* The setjmp()/longjmp(), sigsetjmp()/siglongjmp(). */
39 static sigjmp_buf sigjbuf;
40 static sigset_t sigset4;
43 raise_longjmp (jmp_buf jbuf, int i, int n)
46 raise_longjmp (jbuf, i + 1, n);
58 for (i = 0; i < 10; ++i)
60 if ((ret = setjmp (jbuf)))
63 printf ("%s: secondary setjmp () return, ret=%d\n",
67 fprintf (stderr, "%s: setjmp() returned %d, expected %d\n",
68 __FUNCTION__, ret, i + 1);
74 printf ("%s.%d: done with setjmp(); calling children\n",
77 raise_longjmp (jbuf, 0, i + 1);
79 fprintf (stderr, "%s: raise_longjmp() returned unexpectedly\n",
87 raise_siglongjmp (sigjmp_buf jbuf, int i, int n)
90 raise_siglongjmp (jbuf, i + 1, n);
102 for (i = 0; i < 10; ++i)
104 if ((ret = sigsetjmp (jbuf, 1)))
107 printf ("%s: secondary sigsetjmp () return, ret=%d\n",
111 fprintf (stderr, "%s: sigsetjmp() returned %d, expected %d\n",
112 __FUNCTION__, ret, i + 1);
118 printf ("%s.%d: done with sigsetjmp(); calling children\n",
119 __FUNCTION__, i + 1);
121 raise_siglongjmp (jbuf, 0, i + 1);
123 fprintf (stderr, "%s: raise_siglongjmp() returned unexpectedly\n",
130 sighandler (int signal)
133 printf ("%s: got signal %d\n", __FUNCTION__, signal);
135 sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset4);
137 printf ("%s: back from sigprocmask\n", __FUNCTION__);
139 siglongjmp (sigjbuf, 1);
140 printf ("%s: siglongjmp() returned unexpectedly!\n", __FUNCTION__);
144 main (int argc, char **argv UNUSED)
146 volatile sigset_t sigset1, sigset2, sigset3;
147 volatile struct sigaction act;
152 sigemptyset ((sigset_t *) &sigset1);
153 sigaddset ((sigset_t *) &sigset1, SIGUSR1);
154 sigemptyset ((sigset_t *) &sigset2);
155 sigaddset ((sigset_t *) &sigset2, SIGUSR2);
157 memset ((void *) &act, 0, sizeof (act));
158 act.sa_handler = sighandler;
159 sigaction (SIGTERM, (struct sigaction *) &act, NULL);
164 /* _setjmp() MUST NOT change signal mask: */
165 sigprocmask (SIG_SETMASK, (sigset_t *) &sigset1, NULL);
168 sigemptyset ((sigset_t *) &sigset3);
169 sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3);
170 if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset2,
171 sizeof (sigset_t)) != 0)
173 fprintf (stderr, "FAILURE: _longjmp() manipulated signal mask!\n");
177 printf ("OK: _longjmp() seems not to change signal mask\n");
181 sigprocmask (SIG_SETMASK, (sigset_t *) &sigset2, NULL);
185 /* sigsetjmp(jbuf, 1) MUST preserve signal mask: */
186 sigprocmask (SIG_SETMASK, (sigset_t *) &sigset1, NULL);
187 if (sigsetjmp (sigjbuf, 1))
189 sigemptyset ((sigset_t *) &sigset3);
190 sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3);
191 if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset1,
192 sizeof (sigset_t)) != 0)
195 "FAILURE: siglongjmp() didn't restore signal mask!\n");
199 printf ("OK: siglongjmp() restores signal mask when asked to\n");
203 sigprocmask (SIG_SETMASK, (sigset_t *) &sigset2, NULL);
204 siglongjmp (sigjbuf, 1);
207 /* sigsetjmp(jbuf, 0) MUST NOT preserve signal mask: */
208 sigprocmask (SIG_SETMASK, (sigset_t *) &sigset1, NULL);
209 if (sigsetjmp (sigjbuf, 0))
211 sigemptyset ((sigset_t *) &sigset3);
212 sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3);
213 if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset2,
214 sizeof (sigset_t)) != 0)
217 "FAILURE: siglongjmp() changed signal mask!\n");
221 printf ("OK: siglongjmp() leaves signal mask alone when asked to\n");
225 sigprocmask (SIG_SETMASK, (sigset_t *) &sigset2, NULL);
226 siglongjmp (sigjbuf, 1);
229 /* sigsetjmp(jbuf, 1) MUST preserve signal mask: */
230 sigprocmask (SIG_SETMASK, (sigset_t *) &sigset1, NULL);
231 if (sigsetjmp (sigjbuf, 1))
233 sigemptyset ((sigset_t *) &sigset3);
234 sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3);
235 if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset1,
236 sizeof (sigset_t)) != 0)
239 "FAILURE: siglongjmp() didn't restore signal mask!\n");
243 printf ("OK: siglongjmp() restores signal mask when asked to\n");
247 sigprocmask (SIG_SETMASK, (sigset_t *) &sigset2, NULL);
248 kill (getpid (), SIGTERM);
249 fprintf (stderr, "FAILURE: unexpected return from kill()\n");
253 /* sigsetjmp(jbuf, 0) MUST NOT preserve signal mask: */
254 sigprocmask (SIG_SETMASK, (sigset_t *) &sigset1, NULL);
255 if (sigsetjmp (sigjbuf, 0))
257 sigemptyset ((sigset_t *) &sigset3);
258 sigprocmask (SIG_BLOCK, NULL, (sigset_t *) &sigset3);
259 if (memcmp ((sigset_t *) &sigset3, (sigset_t *) &sigset4,
260 sizeof (sigset_t)) != 0)
263 "FAILURE: siglongjmp() changed signal mask!\n");
267 printf ("OK: siglongjmp() leaves signal mask alone when asked to\n");
271 sigprocmask (SIG_SETMASK, (sigset_t *) &sigset2, NULL);
272 kill (getpid (), SIGTERM);
273 fprintf (stderr, "FAILURE: unexpected return from kill()\n");
279 fprintf (stderr, "FAILURE: detected %d failures\n", nerrors);
283 printf ("SUCCESS\n");