fixes init script for non ipv6 enabled systems #472755
[packages/xinetd.git] / xinetd / signals.c
1 /*
2  * (c) Copyright 1992 by Panagiotis Tsirigotis
3  * (c) Sections Copyright 1998-2001 by Rob Braun
4  * All rights reserved.  The file named COPYRIGHT specifies the terms 
5  * and conditions for redistribution.
6  */
7
8
9 #include "config.h"
10 #if defined(HAVE_STRSIGNAL)
11 #define _GNU_SOURCE
12 #endif
13 #include <sys/types.h>
14 #include <sys/time.h>
15 #include <signal.h>
16 #include <syslog.h>
17 #include <errno.h>
18 #include <string.h>
19 #include <unistd.h>
20 #include <fcntl.h>
21 #include <time.h>
22 #include <sys/ioctl.h>
23 #ifdef HAVE_SYS_FILIO_H
24 #include <sys/filio.h>
25 #endif
26
27 #include "str.h"
28 #include "signals.h"
29 #include "xconfig.h"
30 #include "msg.h"
31 #include "main.h"
32 #include "xtimer.h"
33 #include "child.h"
34 #include "retry.h"
35 #include "reconfig.h"
36 #include "internals.h"
37
38 #ifdef NO_POSIX_TYPES
39 /*
40  * XXX:   here we assume that in the case that NO_POSIX_TYPES is not defined
41  *   (i.e. the system has posix types) the sigset_t is also typedef'd
42  *   to 'int'. Our goal is to work with systems that have defined
43  *   sigset_t but do not yet support the posix signal interface.
44  */
45 typedef int sigset_t ;
46
47 struct sigaction
48 {
49    void         (*sa_handler)(int) ;
50    sigset_t     sa_mask ;
51    int          sa_flags ;
52 } ;
53 #endif   /* NO_POSIX_TYPES */
54
55 static void my_handler( int sig );
56 static void general_handler( int sig );
57
58 typedef void sigfunc( int );
59
60 #define SIGSET_NULL            ((sigset_t *)0)
61 #define SIGVEC_NULL            ((struct sigvec *)0)
62 #define SIGACTION_NULL         ((struct sigaction *)0)
63
64
65 #ifdef NO_POSIX_SIGS
66 #ifdef NO_SIGVEC
67 #define sigmask( sig )                  ( 1 << ( (sig) -1 ) )
68 typedef int (*sighandler_type)() ;
69 #define sigpause( x )
70 #define sigsetmask( x )
71 #endif   /* NO_SIGVEC */
72
73 #define sigsuspend( set )               sigpause( *set )
74 #define sigemptyset( set )              (*set) = 0
75 #define sigaddset( set, sig )           ( ( (*set) |= sigmask( sig ) ), 0 )
76 #define sigismember( set, sig )         ( ( (*set) & sigmask( sig ) ) != 0 )
77
78 /*
79  * Only works for SIG_SETMASK and SIG_UNBLOCK. Also oset must be NULL.
80  */
81 int sigprocmask( int how, sigset_t *set, sigset_t *oset )
82 {
83    if ( how == SIG_BLOCK || oset != NULL )
84    {
85       msg( LOG_ERR, "sigprocmask",
86                            "Bad args: how = %d, oset = %p", how, oset ) ;
87       return( -1 ) ;
88    }
89
90    if ( how == SIG_SETMASK )
91    {
92       (void) sigsetmask( *set ) ;
93       return( 0 ) ;
94    }
95
96    if ( how == SIG_UNBLOCK )
97    {
98       int current_mask = sigblock( 0 ) ;
99
100       (void) sigsetmask( current_mask & ~*set ) ;
101       return( 0 ) ;
102    }
103    /* NOTREACHED */
104 }
105
106
107 /*
108  * NOTE: This is not a complete imitation of sigaction; in particular it
109  *   expects that sap is never NULL and that osap is always NULL.
110  */
111 int sigaction( int sig, struct sigaction *sap, struct sigaction *osap )
112 {
113    if ( sap == NULL || osap != NULL )
114    {
115       msg( LOG_ERR, "sigaction", "Bad args: sap = %p, osap = %p", sap, osap ) ;
116       return( -1 ) ;
117    }
118
119 #ifndef NO_SIGVEC
120    {
121       struct sigvec sv ;
122
123       sv.sv_handler = sap->sa_handler ;
124       sv.sv_mask = sap->sa_mask ;
125       sv.sv_flags = sap->sa_flags ;
126
127       return( sigvec( sig, &sv, SIGVEC_NULL ) ) ;
128    }
129 #else      /* NO_SIGVEC */
130    {
131       sighandler_type new_handler ;
132
133       new_handler = sa.sa_handler ;
134       return( signal( sig, new_handler ) ? 0 : -1 ) ;
135    }
136 #endif   /* ! NO_SIGVEC */
137 }
138
139 #endif   /* NO_POSIX_SIGS */
140
141
142 /*
143  * reset_sigs is the list of signals that we need to reset to SIG_DFL.
144  * Currently, these are the signals whose actions we set to SIG_IGN.
145  * In general, we should also include any signals that have a handler
146  * that does anything other than setting a flag. We need to do this
147  * in case such a signal occurs while a forked process is providing
148  * an internal service.
149  */
150 static sigset_t reset_sigs ;
151
152 /*
153  * nsig is equal to the greatest signal number supported plus 1
154  */
155 static int nsig ;
156
157
158 /*
159  * When this function returns FAILED, we check the errno to determine
160  * if it failed because the signal number specified was invalid.
161  * This allows us to determine the number of supported signals.
162  */
163 static status_e handle_signal( int sig )
164 {
165    struct sigaction      sa ;
166    sigfunc              *sig_handler ;
167
168    sa.sa_flags = 0 ;
169
170    switch ( sig )
171    {
172       case RECONFIG_HARD_SIG:
173       case OLD_RECONFIG_HARD_SIG:
174       case TERMINATION_SIG:
175       case STATE_DUMP_SIG:
176       case CONSISTENCY_CHECK_SIG:
177       case SERVER_EXIT_SIG:
178       case QUIT_SIG:
179          sig_handler = my_handler ;
180          break ;
181
182       case SIGTTIN:
183       case SIGTTOU:
184       case SIGTSTP:
185          if ( debug.on )
186             return( OK ) ;
187          /* FALL THROUGH */
188           
189       /*
190        * We may receive a SIGPIPE when handling an internal stream 
191        * service and the other end closes the connection.
192        * We only care about internal services that don't require forking.
193        */
194       case SIGPIPE:
195          sig_handler = SIG_IGN ;
196          sigaddset( &reset_sigs, sig ) ;
197          break ;
198
199       case SIGKILL:
200       case SIGSTOP:
201          return( OK ) ;         /* we can't catch these two */
202       
203       /*
204        * If the following two cases are included, SIGSEGV and SIGBUS will
205        * cause core dumps. We want that to happen when we are debugging
206        * xinetd (i.e. DEBUG is defined) and we are not debugging the
207        * signal recovery code (i.e. DEBUG_SIGNALS is not defined).
208        */
209       case SIGSEGV:
210       case SIGBUS:
211 #if defined( DEBUG ) && !defined( DEBUG_SIGNALS )
212          return( OK ) ;
213 #else
214          sig_handler = general_handler ;
215          break;
216 #endif
217       case SIGTRAP:
218          if ( debug.on )
219             return( OK ) ;
220       
221       default:
222          sig_handler = general_handler ;
223    }
224
225    sigemptyset( &sa.sa_mask ) ;
226    sa.sa_handler = sig_handler ;
227    return( ( sigaction( sig, &sa, SIGACTION_NULL ) == -1 ) ? FAILED : OK ) ;
228 }
229
230
231 /*
232  * Install signal handlers for all signals that can be caught.
233  * This implies that no core dumps are generated by default.
234  */
235 status_e signal_init(void)
236 {
237    int      sig ;
238    const char    *func = "install_signal_handlers" ;
239
240    sigemptyset( &reset_sigs ) ;
241
242    if ( pipe(signals_pending) ||
243         fcntl(signals_pending[0], F_SETFD, FD_CLOEXEC) ||
244         fcntl(signals_pending[1], F_SETFD, FD_CLOEXEC) ) {
245       msg( LOG_CRIT, func, "Failed to create signal pipe: %m" );
246       return( FAILED );
247    }
248
249    for ( sig = 1 ;; sig++ )
250       if ( handle_signal( sig ) == FAILED ) {
251          if ( errno == EINVAL )
252          {
253             nsig = sig ;
254             break ;
255          }
256          else
257          {
258             msg( LOG_CRIT, func,
259                "Failed to install signal handler for signal %s: %m",
260                   sig_name( sig ) ) ;
261             return( FAILED ) ;
262          }
263       }
264    return( OK ) ;
265 }
266
267 #define MAX_SIGNAL_COUNT               50
268 #define MAX_INTERVAL_SIGNAL_COUNT      10
269 #define SIGNAL_INTERVAL                 1      /* second */
270 /*
271  * This function handles SIGSEGV and SIGBUS.
272  * Emergency action is taken if a certain number (MAX_SIGNAL_COUNT) of 
273  * these signals is received over the lifetime of the program OR 
274  * if a certain number (MAX_INTERVAL_SIGNAL_COUNT) of these signals 
275  * is received within a certain time interval (SIGNAL_INTERVAL).
276  *
277  * The action depends on the type of the emergency:
278  *      Case 1: MAX_INTERVAL_SIGNAL_COUNT is exceeded
279  *         If a setjmp environment is available, do a longjmp, otherwise exit
280  *      Case 2: MAX_SIGNAL_COUNT is exceeded
281  *         Exit
282  *
283  * NOTE: We try to send a message to the log only once to avoid
284  *         looping in this function (in case there is a bug in msg())
285  */
286 static void bad_signal(void)
287 {
288    static time_t   interval_start ;
289    static volatile int interval_signal_count ;
290    static volatile int total_signal_count ;
291    time_t          current_time ;
292    const char     *func = "bad_signal" ;
293
294    total_signal_count++ ;
295    if ( total_signal_count == MAX_SIGNAL_COUNT )
296    {
297       msg( LOG_CRIT, func,
298             "Received %d bad signals. Exiting...", total_signal_count ) ;
299       exit( 1 ) ;
300    }
301    else if ( total_signal_count > MAX_SIGNAL_COUNT )
302       _exit( 1 ) ;      /* in case of a problem in exit(3) */
303    
304    (void) time( &current_time ) ;
305
306    if ( interval_signal_count > 0 &&
307             current_time - interval_start <= SIGNAL_INTERVAL )
308    {
309       interval_signal_count++ ;
310       if ( interval_signal_count == MAX_INTERVAL_SIGNAL_COUNT )
311       {
312          if ( ps.rws.env_is_valid )
313          {
314             interval_start = current_time ;
315             interval_signal_count = 1 ;
316             msg( LOG_ERR, func, "Resetting..." ) ;
317             siglongjmp( ps.rws.env, 1 ) ;
318             /* NOTREACHED */
319          }
320          msg( LOG_CRIT, func,
321             "Received %d signals in %d seconds. Exiting...",
322                interval_signal_count, SIGNAL_INTERVAL ) ;
323          exit( 1 ) ;
324       }
325       else if ( interval_signal_count > MAX_INTERVAL_SIGNAL_COUNT )
326          _exit( 1 ) ;         /* shouldn't happen */
327    }
328    else
329    {
330       interval_start = current_time ;
331       interval_signal_count = 1 ;
332    }
333 }
334
335 char *sig_name( int sig )
336 {
337    static char signame_buf[ 30 ] ;
338
339 #if defined(HAVE_STRSIGNAL)
340    /* Use strsignal and remove the old sys_siglist stuff */
341    if ( sig < NSIG )
342       return( strx_sprint( signame_buf, sizeof( signame_buf ) - 1,
343                "%d (%s)", sig, strsignal(sig) ) ) ;
344 #else
345 #if defined(HAVE_SYS_SIGLIST)
346    if ( sig < NSIG )
347       return( strx_sprint( signame_buf, sizeof( signame_buf ) - 1,
348                "%d (%s)", sig, sys_siglist[sig] ) ) ;
349 #endif
350 #endif
351    return( strx_sprint( signame_buf, sizeof( signame_buf ) - 1, "%d", sig ) ) ;
352 }
353
354
355 /*
356  * For SIGSEGV and SIGBUS we invoke the bad_signal() function
357  *
358  * For other signals, we just log the fact that they occured.
359  * SIGINT is a special case since in debug.on mode, it will 
360  * cause termination.
361  */
362
363 static void general_handler( int sig )
364 {
365    sigset_t badsigs ;
366    const char *func = "general_handler" ;
367
368    /*
369     * Do this here to catch problems like SIGSEGV in msg()
370     */
371    sigemptyset( &badsigs ) ;
372    sigaddset( &badsigs, sig ) ;
373    (void) sigprocmask( SIG_UNBLOCK, &badsigs, SIGSET_NULL ) ;
374
375    switch ( sig )
376    {
377       case SIGBUS:
378       case SIGSEGV:
379          msg( LOG_CRIT, func, "(%d) Unexpected signal: %s", 
380                         getpid(), sig_name( sig ) ) ;
381          if ( debug.on )
382          {
383             /* Generate a core dump */
384             signal(SIGABRT, SIG_DFL);
385             abort();
386          }
387          else
388             bad_signal() ;
389          break ;
390       
391       default:
392          msg( LOG_NOTICE, func, "Unexpected signal %s", sig_name( sig ) ) ;
393          if ( debug.on && sig == SIGINT )
394             exit( 1 ) ;
395    }
396 }
397
398
399 /*
400  * The job of this function is to write the signal received to the
401  * pipe of pending signals, which is in the main select loop.
402  */
403 static void my_handler( int sig )
404 {
405    int ret_val;
406    int saved_errno = errno;
407 #if NSIG < 256
408    unsigned char sig_byte;
409    if (signals_pending[1] < 0) return;
410    if (sig >= 256) return;
411    sig_byte = sig;
412    do
413    {
414       ret_val = write(signals_pending[1], &sig_byte, 1);
415    } while (ret_val == -1 && errno == EINTR);
416 #else
417    if (signals_pending[1] < 0) return;
418    do
419    {
420       ret_val = write(signals_pending[1], &sig, sizeof(int));
421    } while (ret_val == -1 && errno == EINTR);
422 #endif
423    errno = saved_errno;
424 }
425
426
427 /*
428  * Reset all signals to default action. Reset the signal mask
429  *
430  * This function is invoked from a forked process. That is why we
431  * invoke _exit instead of exit (to avoid the possible stdio buffer flushes)
432  */
433 void signal_default_state(void)
434 {
435    int sig ;
436    sigset_t empty ;
437
438    for ( sig = 1 ; sig < nsig ; sig++ )
439       if ( sigismember( &reset_sigs, sig ) == 1 )
440          if ( signal( sig, SIG_DFL ) == SIG_ERR )
441          {
442             msg( LOG_ERR, "reset_signals",
443                "signal failed for signal %s: %m", sig_name( sig ) ) ;
444             if ( debug.on )
445                _exit( 1 ) ;
446          }
447       
448    sigemptyset( &empty ) ;
449    (void) sigprocmask( SIG_SETMASK, &empty, SIGSET_NULL ) ;
450 }
451
452 void check_pipe(void)
453 {
454    int i;
455 #if NSIG < 256
456    unsigned char sig;
457 #else
458    int sig;
459 #endif
460    const char *func = "check_pipe";
461
462    if (signals_pending[0] < 0) return;
463
464    if( ioctl(signals_pending[0], FIONREAD, &i) != 0 ) {
465       msg(LOG_ERR, func, "Can't get the number of pending signals: %m");
466       return;
467    }
468 #if NSIG >= 256
469    i /= sizeof(int);
470 #endif
471
472    while( --i >= 0 ) {
473       int ret_val;
474       do
475       {
476          ret_val = read(signals_pending[0], &sig, sizeof(sig));
477       } while (ret_val == -1 && errno == EINTR);
478       if (ret_val != sizeof(sig) ) {
479          msg(LOG_ERR, func, "Error retrieving pending signal: %m");
480          return;
481       }
482
483       if( debug.on ) {
484          msg(LOG_DEBUG, func, "Got signal %s", sig_name(sig));
485       }
486
487       switch(sig) {
488          case SERVER_EXIT_SIG:       child_exit();           break;
489          case RECONFIG_HARD_SIG:     hard_reconfig();        break;
490          case OLD_RECONFIG_HARD_SIG: hard_reconfig();        break;
491          case TERMINATION_SIG:       terminate_program();    break;
492          case STATE_DUMP_SIG:        dump_internal_state();  break;
493          case CONSISTENCY_CHECK_SIG: user_requested_check(); break;
494          case QUIT_SIG:              quit_program();         break;
495          default:
496             msg(LOG_ERR, func, "unexpected signal: %s in signal pipe", 
497                sig_name(sig));
498       }
499    }
500 }