12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26 /* This is a special library that should be loaded before libc & 27 * libthread to interpose the signal handler installation functions: 28 * sigaction(), signal(), sigset(). 29 * Used for signal-chaining. See RFE 4381843. 30 */ 31 32 #include <dlfcn.h> 33 #include <errno.h> 34 #include <pthread.h> 35 #include <signal.h> 36 #include <stdio.h> 37 #include <stdlib.h> 38 #include <string.h> 39 40 #if (__STDC_VERSION__ >= 199901L) 41 #include <stdbool.h> 42 #else 43 #define bool int 44 #define true 1 45 #define false 0 46 #endif 47 48 #ifdef SOLARIS 49 #define MAX_SIGNALS (SIGRTMAX+1) 50 51 /* On solaris, MAX_SIGNALS is a macro, not a constant, so we must allocate sact dynamically. */ 191 * handlers and save the old ones. jvm uses sigaction(). 192 * Leave the piece here just in case. */ 193 oldhandler = call_os_signal(sig, disp, is_sigset); 194 save_signal_handler(sig, oldhandler, is_sigset); 195 196 /* Record the signals used by jvm */ 197 sigaddset(&jvmsigs, sig); 198 199 signal_unlock(); 200 return oldhandler; 201 } else { 202 /* jvm has no relation with this signal (yet). Install the 203 * the handler. */ 204 oldhandler = call_os_signal(sig, disp, is_sigset); 205 206 signal_unlock(); 207 return oldhandler; 208 } 209 } 210 211 sa_handler_t signal(int sig, sa_handler_t disp) { 212 if (sig < 0 || sig >= MAX_SIGNALS) { 213 errno = EINVAL; 214 return SIG_ERR; 215 } 216 217 return set_signal(sig, disp, false); 218 } 219 220 sa_handler_t sigset(int sig, sa_handler_t disp) { 221 #ifdef _ALLBSD_SOURCE 222 printf("sigset() is not supported by BSD"); 223 exit(0); 224 #else 225 if (sig < 0 || sig >= MAX_SIGNALS) { 226 errno = EINVAL; 227 return (sa_handler_t)-1; 228 } 229 230 return set_signal(sig, disp, true); 231 #endif 232 } 233 234 static int call_os_sigaction(int sig, const struct sigaction *act, 235 struct sigaction *oact) { 236 if (os_sigaction == NULL) { 237 os_sigaction = (sigaction_t)dlsym(RTLD_NEXT, "sigaction"); 238 if (os_sigaction == NULL) { 239 printf("%s\n", dlerror()); 240 exit(0); 241 } 242 } 243 return (*os_sigaction)(sig, act, oact); 244 } 245 246 int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { 247 int res; 248 bool sigused; 249 struct sigaction oldAct; 250 251 if (sig < 0 || sig >= MAX_SIGNALS) { 252 errno = EINVAL; 253 return -1; 254 } 255 256 #ifdef MACOSX 257 if (reentry) { 258 return call_os_sigaction(sig, act, oact); 259 } 260 #endif 261 262 signal_lock(); 263 264 allocate_sact(); 265 sigused = sigismember(&jvmsigs, sig); 266 if (jvm_signal_installed && sigused) { | 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26 /* This is a special library that should be loaded before libc & 27 * libthread to interpose the signal handler installation functions: 28 * sigaction(), signal(), sigset(). 29 * Used for signal-chaining. See RFE 4381843. 30 */ 31 32 #include "jni.h" 33 34 #ifdef SOLARIS 35 /* Our redeclarations of the system functions must not have a less 36 * restrictive linker scoping, so we have to declare them as JNIEXPORT 37 * before including signal.h */ 38 #include "sys/signal.h" 39 JNIEXPORT void (*signal(int sig, void (*disp)(int)))(int); 40 JNIEXPORT void (*sigset(int sig, void (*disp)(int)))(int); 41 JNIEXPORT int sigaction(int sig, const struct sigaction *act, struct sigaction *oact); 42 #endif 43 44 #include <dlfcn.h> 45 #include <errno.h> 46 #include <pthread.h> 47 #include <signal.h> 48 #include <stdio.h> 49 #include <stdlib.h> 50 #include <string.h> 51 52 #if (__STDC_VERSION__ >= 199901L) 53 #include <stdbool.h> 54 #else 55 #define bool int 56 #define true 1 57 #define false 0 58 #endif 59 60 #ifdef SOLARIS 61 #define MAX_SIGNALS (SIGRTMAX+1) 62 63 /* On solaris, MAX_SIGNALS is a macro, not a constant, so we must allocate sact dynamically. */ 203 * handlers and save the old ones. jvm uses sigaction(). 204 * Leave the piece here just in case. */ 205 oldhandler = call_os_signal(sig, disp, is_sigset); 206 save_signal_handler(sig, oldhandler, is_sigset); 207 208 /* Record the signals used by jvm */ 209 sigaddset(&jvmsigs, sig); 210 211 signal_unlock(); 212 return oldhandler; 213 } else { 214 /* jvm has no relation with this signal (yet). Install the 215 * the handler. */ 216 oldhandler = call_os_signal(sig, disp, is_sigset); 217 218 signal_unlock(); 219 return oldhandler; 220 } 221 } 222 223 JNIEXPORT sa_handler_t signal(int sig, sa_handler_t disp) { 224 if (sig < 0 || sig >= MAX_SIGNALS) { 225 errno = EINVAL; 226 return SIG_ERR; 227 } 228 229 return set_signal(sig, disp, false); 230 } 231 232 JNIEXPORT sa_handler_t sigset(int sig, sa_handler_t disp) { 233 #ifdef _ALLBSD_SOURCE 234 printf("sigset() is not supported by BSD"); 235 exit(0); 236 #else 237 if (sig < 0 || sig >= MAX_SIGNALS) { 238 errno = EINVAL; 239 return (sa_handler_t)-1; 240 } 241 242 return set_signal(sig, disp, true); 243 #endif 244 } 245 246 static int call_os_sigaction(int sig, const struct sigaction *act, 247 struct sigaction *oact) { 248 if (os_sigaction == NULL) { 249 os_sigaction = (sigaction_t)dlsym(RTLD_NEXT, "sigaction"); 250 if (os_sigaction == NULL) { 251 printf("%s\n", dlerror()); 252 exit(0); 253 } 254 } 255 return (*os_sigaction)(sig, act, oact); 256 } 257 258 JNIEXPORT int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { 259 int res; 260 bool sigused; 261 struct sigaction oldAct; 262 263 if (sig < 0 || sig >= MAX_SIGNALS) { 264 errno = EINVAL; 265 return -1; 266 } 267 268 #ifdef MACOSX 269 if (reentry) { 270 return call_os_sigaction(sig, act, oact); 271 } 272 #endif 273 274 signal_lock(); 275 276 allocate_sact(); 277 sigused = sigismember(&jvmsigs, sig); 278 if (jvm_signal_installed && sigused) { |