Changeset 7233f68
- Timestamp:
- 2014-11-26T05:25:05Z (10 years ago)
- Branches:
- master
- Children:
- bc7a0d4
- Parents:
- 6f6725c
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
unix.c
r6f6725c r7233f68 48 48 global_t global; /* Against global namespace pollution */ 49 49 50 static void sighandler( int signal ); 50 static int signal_shutdown_pipe[2] = { -1, -1 }; 51 static void sighandler_shutdown( int signal ); 52 static void sighandler_crash( int signal ); 51 53 52 54 static int crypt_main( int argc, char *argv[] ); … … 156 158 /* Catch some signals to tell the user what's happening before quitting */ 157 159 memset( &sig, 0, sizeof( sig ) ); 158 sig.sa_handler = sighandler;160 sig.sa_handler = SIG_IGN; 159 161 sigaction( SIGCHLD, &sig, &old ); 160 162 sigaction( SIGPIPE, &sig, &old ); 161 163 sig.sa_flags = SA_RESETHAND; 162 sigaction( SIGINT, &sig, &old ); 163 sigaction( SIGILL, &sig, &old ); 164 sigaction( SIGBUS, &sig, &old ); 165 sigaction( SIGFPE, &sig, &old ); 164 sig.sa_handler = sighandler_crash; 166 165 sigaction( SIGSEGV, &sig, &old ); 167 sigaction( SIGTERM, &sig, &old ); 168 sigaction( SIGQUIT, &sig, &old ); 169 sigaction( SIGXCPU, &sig, &old ); 166 167 /* Use a pipe for SIGTERM/SIGINT so the actual signal handler doesn't do anything unsafe */ 168 if ( pipe( signal_shutdown_pipe ) == 0 ) { 169 b_input_add( signal_shutdown_pipe[0], B_EV_IO_READ, bitlbee_shutdown, NULL ); 170 sig.sa_handler = sighandler_shutdown; 171 sigaction( SIGINT, &sig, &old ); 172 sigaction( SIGTERM, &sig, &old ); 173 } 170 174 171 175 if( !getuid() || !geteuid() ) … … 259 263 } 260 264 261 static void sighandler( int signal ) 262 { 263 /* FIXME: Calling log_message() here is not a very good idea! */ 264 265 if( signal == SIGTERM || signal == SIGQUIT || signal == SIGINT ) 266 { 267 static int first = 1; 268 269 if( first ) 270 { 271 /* We don't know what we were doing when this signal came in. It's not safe to touch 272 the user data now (not to mention writing them to disk), so add a timer. */ 273 274 log_message( LOGLVL_ERROR, "SIGTERM received, cleaning up process." ); 275 b_timeout_add( 1, (b_event_handler) bitlbee_shutdown, NULL ); 276 277 first = 0; 278 } 279 else 280 { 281 /* Well, actually, for now we'll never need this part because this signal handler 282 will never be called more than once in a session for a non-SIGPIPE signal... 283 But just in case we decide to change that: */ 284 285 log_message( LOGLVL_ERROR, "SIGTERM received twice, so long for a clean shutdown." ); 286 raise( signal ); 287 } 288 } 289 else if( signal == SIGCHLD ) 290 { 291 pid_t pid; 292 int st; 293 294 while( ( pid = waitpid( 0, &st, WNOHANG ) ) > 0 ) 295 { 296 if( WIFSIGNALED( st ) ) 297 log_message( LOGLVL_INFO, "Client %d terminated normally. (status = %d)", (int) pid, WEXITSTATUS( st ) ); 298 else if( WIFEXITED( st ) ) 299 log_message( LOGLVL_INFO, "Client %d killed by signal %d.", (int) pid, WTERMSIG( st ) ); 300 } 301 } 302 else if( signal != SIGPIPE ) 303 { 304 log_message( LOGLVL_ERROR, "Fatal signal received: %d. That's probably a bug.", signal ); 305 raise( signal ); 306 } 265 /* Signal handler for SIGTERM and SIGINT */ 266 static void sighandler_shutdown( int signal ) 267 { 268 /* Write a single null byte to the pipe, just to send a message to the main loop. 269 * This gets handled by bitlbee_shutdown (the b_input_add callback for this pipe) */ 270 write( signal_shutdown_pipe[1], "", 1 ); 271 } 272 273 /* Signal handler for SIGSEGV 274 * A desperate attempt to tell the user that everything is wrong in the world. 275 * Avoids using irc_abort() because it has several unsafe calls to malloc */ 276 static void sighandler_crash( int signal ) 277 { 278 GSList *l; 279 const char *message = "ERROR :BitlBee crashed! (SIGSEGV received)\r\n"; 280 int len = strlen(message); 281 282 for (l = irc_connection_list; l; l = l->next ) { 283 irc_t *irc = l->data; 284 write( irc->fd, message, len ); 285 } 286 287 raise( signal ); 307 288 } 308 289
Note: See TracChangeset
for help on using the changeset viewer.