1 /* $OpenBSD: setsignal.c,v 1.3 2007/10/07 16:41:05 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 #ifndef lint 25 static const char rcsid[] = 26 "@(#) $Id: setsignal.c,v 1.3 2007/10/07 16:41:05 deraadt Exp $ (LBL)"; 27 #endif 28 29 #include <sys/types.h> 30 31 #ifdef HAVE_MEMORY_H 32 #include <memory.h> 33 #endif 34 #include <signal.h> 35 #ifdef HAVE_SIGACTION 36 #include <string.h> 37 #endif 38 39 #include "gnuc.h" 40 #ifdef HAVE_OS_PROTO_H 41 #include "os-proto.h" 42 #endif 43 44 #include "setsignal.h" 45 46 /* 47 * An os independent signal() with BSD semantics, e.g. the signal 48 * catcher is restored following service of the signal. 49 * 50 * When sigset() is available, signal() has SYSV semantics and sigset() 51 * has BSD semantics and call interface. Unfortunately, Linux does not 52 * have sigset() so we use the more complicated sigaction() interface 53 * there. 54 * 55 * Did I mention that signals suck? 56 */ 57 RETSIGTYPE 58 (*setsignal (int sig, RETSIGTYPE (*func)(int)))(int) 59 { 60 #ifdef HAVE_SIGACTION 61 struct sigaction old, new; 62 63 memset(&new, 0, sizeof(new)); 64 new.sa_handler = func; 65 #ifdef SA_RESTART 66 new.sa_flags |= SA_RESTART; 67 #endif 68 if (sigaction(sig, &new, &old) < 0) 69 return (SIG_ERR); 70 return (old.sa_handler); 71 72 #else 73 #ifdef HAVE_SIGSET 74 return (sigset(sig, func)); 75 #else 76 return (signal(sig, func)); 77 #endif 78 #endif 79 } 80 81