1 /* $OpenBSD: jmptest.c,v 1.7 2003/09/02 23:52:16 david Exp $ */ 2 /* $NetBSD: jmptest.c,v 1.2 1995/01/01 20:55:35 jtc Exp $ */ 3 4 /* 5 * Copyright (c) 1994 Christopher G. Demetriou 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Christopher G. Demetriou 19 * for the NetBSD Project. 20 * 4. The name of the author may not be used to endorse or promote products 21 * derived from this software without specific prior written permission 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include <sys/types.h> 36 #include <err.h> 37 #include <setjmp.h> 38 #include <signal.h> 39 #include <stdio.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #include <unistd.h> 43 44 #if (TEST_SETJMP + TEST_U_SETJMP + TEST_SIGSETJMP) != 1 45 #error one of TEST_SETJMP, TEST_U_SETJMP, or TEST_SIGSETJMP must be defined 46 #endif 47 48 #ifdef TEST_SETJMP 49 #define BUF jmp_buf 50 #define SET(b, m) setjmp(b) 51 #define JMP(b, v) longjmp(b, v) 52 #endif 53 54 #ifdef TEST_U_SETJMP 55 #define BUF jmp_buf 56 #define SET(b, m) _setjmp(b) 57 #define JMP(b, v) _longjmp(b, v) 58 #endif 59 60 #ifdef TEST_SIGSETJMP 61 #define BUF sigjmp_buf 62 #define SET(b, m) sigsetjmp(b, m) 63 #define JMP(b, v) siglongjmp(b, v) 64 #endif 65 66 int expectsignal; 67 68 static void 69 aborthandler(int signo) 70 { 71 72 if (expectsignal) 73 _exit(0); 74 else { 75 warnx("kill(SIGABRT) succeeded"); 76 _exit(1); 77 } 78 } 79 80 int 81 main(int argc, char *argv[]) 82 { 83 struct sigaction sa; 84 BUF jb; 85 sigset_t ss; 86 int i, x; 87 88 i = getpid(); 89 90 #ifdef TEST_SETJMP 91 expectsignal = 0; 92 #endif 93 #ifdef TEST_U_SETJMP 94 expectsignal = 1; 95 #endif 96 #ifdef TEST_SIGSETJMP 97 if (argc != 2 || 98 (strcmp(argv[1], "save") && strcmp(argv[1], "nosave"))) { 99 fprintf(stderr, "usage: %s [save|nosave]\n", argv[0]); 100 exit(1); 101 } 102 expectsignal = (strcmp(argv[1], "save") != 0); 103 #endif 104 105 sa.sa_handler = aborthandler; 106 sigemptyset(&sa.sa_mask); 107 sa.sa_flags = 0; 108 if (sigaction(SIGABRT, &sa, NULL) == -1) 109 err(1, "sigaction failed"); 110 111 if (sigemptyset(&ss) == -1) 112 err(1, "sigemptyset failed"); 113 if (sigaddset(&ss, SIGABRT) == -1) 114 err(1, "sigaddset failed"); 115 if (sigprocmask(SIG_BLOCK, &ss, NULL) == -1) 116 err(1, "sigprocmask (1) failed"); 117 118 x = SET(jb, !expectsignal); 119 if (x != 0) { 120 if (x != i) 121 errx(1, "setjmp returned wrong value"); 122 123 kill(i, SIGABRT); 124 if (expectsignal) 125 errx(1, "kill(SIGABRT) failed"); 126 else 127 exit(0); 128 } 129 130 if (sigprocmask(SIG_UNBLOCK, &ss, NULL) == -1) 131 err(1, "sigprocmask (2) failed"); 132 133 JMP(jb, i); 134 135 errx(1, "jmp failed"); 136 } 137