Browse Source

Terminate cleanly on SIGINT or SIGHUP

tags/v0.9.3
Michael Brown 19 years ago
parent
commit
c5a9c38606
1 changed files with 41 additions and 11 deletions
  1. 41
    11
      src/util/hijack.c

+ 41
- 11
src/util/hijack.c View File

40
 
40
 
41
 static int daemonised = 0;
41
 static int daemonised = 0;
42
 
42
 
43
+static int signalled = 0;
44
+
45
+static void flag_signalled ( int signal __attribute__ (( unused )) ) {
46
+	signalled = 1;
47
+}
48
+
43
 /**
49
 /**
44
  * Log error message
50
  * Log error message
45
  *
51
  *
363
 
369
 
364
 	logmsg ( LOG_INFO, "Listening on %s\n", listener->sun.sun_path );
370
 	logmsg ( LOG_INFO, "Listening on %s\n", listener->sun.sun_path );
365
 
371
 
366
-	while ( 1 ) {
367
-		/* Accept new connection */
372
+	while ( ! signalled ) {
373
+		/* Accept new connection, interruptibly */
374
+		siginterrupt ( SIGINT, 1 );
375
+		siginterrupt ( SIGHUP, 1 );
368
 		fd = accept ( listener->fd, NULL, 0 );
376
 		fd = accept ( listener->fd, NULL, 0 );
377
+		siginterrupt ( SIGINT, 0 );
378
+		siginterrupt ( SIGHUP, 0 );
369
 		if ( fd < 0 ) {
379
 		if ( fd < 0 ) {
370
-			logmsg ( LOG_ERR, "accept failed: %s\n",
371
-				 strerror ( errno ) );
372
-			goto err;
380
+			if ( errno == EINTR ) {
381
+				continue;
382
+			} else {
383
+				logmsg ( LOG_ERR, "accept failed: %s\n",
384
+					 strerror ( errno ) );
385
+				goto err;
386
+			}
373
 		}
387
 		}
374
 
388
 
375
 		/* Fork child process */
389
 		/* Fork child process */
389
 		close ( fd );
403
 		close ( fd );
390
 	}
404
 	}
391
 
405
 
406
+	logmsg ( LOG_INFO, "Stopped listening on %s\n",
407
+		 listener->sun.sun_path );
392
 	return 0;
408
 	return 0;
393
 
409
 
394
  err:
410
  err:
527
 int main ( int argc, char **argv ) {
543
 int main ( int argc, char **argv ) {
528
 	struct hijack_options options;
544
 	struct hijack_options options;
529
 	struct hijack_listener listener;
545
 	struct hijack_listener listener;
530
-	struct sigaction sigchld;
546
+	struct sigaction sa;
531
 
547
 
532
 	/* Parse command-line options */
548
 	/* Parse command-line options */
533
 	if ( parse_options ( argc, argv, &options ) < 0 )
549
 	if ( parse_options ( argc, argv, &options ) < 0 )
547
 	}
563
 	}
548
 
564
 
549
 	/* Avoid creating zombies */
565
 	/* Avoid creating zombies */
550
-	memset ( &sigchld, 0, sizeof ( sigchld ) );
551
-	sigchld.sa_handler = SIG_IGN;
552
-	sigchld.sa_flags = SA_NOCLDWAIT;
553
-	if ( sigaction ( SIGCHLD, &sigchld, NULL ) < 0 ) {
554
-		logmsg ( LOG_ERR, "Could not set signal handler: %s",
566
+	memset ( &sa, 0, sizeof ( sa ) );
567
+	sa.sa_handler = SIG_IGN;
568
+	sa.sa_flags = SA_RESTART | SA_NOCLDWAIT;
569
+	if ( sigaction ( SIGCHLD, &sa, NULL ) < 0 ) {
570
+		logmsg ( LOG_ERR, "Could not set SIGCHLD handler: %s",
571
+			 strerror ( errno ) );
572
+		exit ( 1 );
573
+	}
574
+
575
+	/* Set 'signalled' flag on SIGINT or SIGHUP */
576
+	sa.sa_handler = flag_signalled;
577
+	sa.sa_flags = SA_RESTART | SA_RESETHAND;
578
+	if ( sigaction ( SIGINT, &sa, NULL ) < 0 ) {
579
+		logmsg ( LOG_ERR, "Could not set SIGINT handler: %s",
580
+			 strerror ( errno ) );
581
+		exit ( 1 );
582
+	}
583
+	if ( sigaction ( SIGHUP, &sa, NULL ) < 0 ) {
584
+		logmsg ( LOG_ERR, "Could not set SIGHUP handler: %s",
555
 			 strerror ( errno ) );
585
 			 strerror ( errno ) );
556
 		exit ( 1 );
586
 		exit ( 1 );
557
 	}
587
 	}

Loading…
Cancel
Save