1 /* $OpenBSD: setsignal.c,v 1.4 2009/10/27 23:59:57 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 1997 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that: (1) source code distributions 9 * retain the above copyright notice and this paragraph in its entirety, (2) 10 * distributions including binary code include the above copyright notice and 11 * this paragraph in its entirety in the documentation or other materials 12 * provided with the distribution, and (3) all advertising materials mentioning 13 * features or use of this software display the following acknowledgement: 14 * ``This product includes software developed by the University of California, 15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 16 * the University nor the names of its contributors may be used to endorse 17 * or promote products derived from this software without specific prior 18 * written permission. 19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 22 */ 23 24 #include <sys/types.h> 25 26 #ifdef HAVE_MEMORY_H 27 #include <memory.h> 28 #endif 29 #include <signal.h> 30 #ifdef HAVE_SIGACTION 31 #include <string.h> 32 #endif 33 34 #include "gnuc.h" 35 #ifdef HAVE_OS_PROTO_H 36 #include "os-proto.h" 37 #endif 38 39 #include "setsignal.h" 40 41 /* 42 * An os independent signal() with BSD semantics, e.g. the signal 43 * catcher is restored following service of the signal. 44 * 45 * When sigset() is available, signal() has SYSV semantics and sigset() 46 * has BSD semantics and call interface. Unfortunately, Linux does not 47 * have sigset() so we use the more complicated sigaction() interface 48 * there. 49 * 50 * Did I mention that signals suck? 51 */ 52 RETSIGTYPE 53 (*setsignal (int sig, RETSIGTYPE (*func)(int)))(int) 54 { 55 #ifdef HAVE_SIGACTION 56 struct sigaction old, new; 57 58 memset(&new, 0, sizeof(new)); 59 new.sa_handler = func; 60 #ifdef SA_RESTART 61 new.sa_flags |= SA_RESTART; 62 #endif 63 if (sigaction(sig, &new, &old) < 0) 64 return (SIG_ERR); 65 return (old.sa_handler); 66 67 #else 68 #ifdef HAVE_SIGSET 69 return (sigset(sig, func)); 70 #else 71 return (signal(sig, func)); 72 #endif 73 #endif 74 } 75 76