Browse code

- changed signal handling, added an attendant process

Andrei Pelinescu-Onciul authored on 11/07/2002 14:39:30
Showing 4 changed files
... ...
@@ -8,7 +8,7 @@
8 8
 VERSION = 0
9 9
 PATCHLEVEL = 8
10 10
 SUBLEVEL = 7
11
-EXTRAVERSION = -3-ipv6
11
+EXTRAVERSION = -4-ipv6
12 12
 
13 13
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
14 14
 OS = $(shell uname -s)
... ...
@@ -204,6 +204,7 @@ unsigned int maxbuffer = MAX_RECV_BUFFER_SIZE; /* maximum buffer size we do
204 204
 int children_no = 0;			/* number of children processing requests */
205 205
 int *pids=0;					/*array with childrens pids, 0= main proc,
206 206
 									alloc'ed in shared mem if possible*/
207
+int sig_flag = 0;              /* last signal received */
207 208
 int debug = 0;
208 209
 int dont_fork = 0;
209 210
 int log_stderr = 0;
... ...
@@ -355,6 +356,92 @@ error:
355 356
 
356 357
 
357 358
 
359
+void handle_sigs()
360
+{
361
+	pid_t	chld;
362
+	int	chld_status;
363
+
364
+	switch(sig_flag){
365
+		case 0: break; /* do nothing*/
366
+		case SIGINT:
367
+		case SIGPIPE:
368
+		case SIGTERM:
369
+			/* we end the program in all these cases */
370
+			if (sig_flag==SIGINT)
371
+				DBG("INT received, program terminates\n");
372
+			else if (sig_flag==SIGPIPE)
373
+				DBG("SIGPIPE rreceived, program terminates\n");
374
+			else
375
+				DBG("SIGTERM received, program terminates\n");
376
+				
377
+			destroy_modules();
378
+#ifdef PKG_MALLOC
379
+			LOG(L_INFO, "Memory status (pkg):\n");
380
+			pkg_status();
381
+#endif
382
+#ifdef SHM_MEM
383
+			LOG(L_INFO, "Memory status (shm):\n");
384
+			shm_status();
385
+			/* zero all shmem alloc vars that we still use */
386
+			pids=0;
387
+			shm_mem_destroy();
388
+#endif
389
+			if (pid_file) unlink(pid_file);
390
+			/* kill children also*/
391
+			kill(0, SIGTERM);
392
+			dprint("Thank you for flying " NAME "\n");
393
+			exit(0);
394
+			break;
395
+			
396
+		case SIGUSR1:
397
+#ifdef STATS
398
+			dump_all_statistic();
399
+#endif
400
+#ifdef PKG_MALLOC
401
+			LOG(L_INFO, "Memory status (pkg):\n");
402
+			pkg_status();
403
+#endif
404
+#ifdef SHM_MEM
405
+			LOG(L_INFO, "Memory status (shm):\n");
406
+			shm_status();
407
+#endif
408
+			break;
409
+			
410
+		case SIGCHLD:
411
+			while ((chld=waitpid( -1, &chld_status, WNOHANG ))>0) {
412
+				if (WIFEXITED(chld_status)) 
413
+					LOG(L_INFO, "child process %d exited normally,"
414
+							" status=%d\n", chld, 
415
+							WEXITSTATUS(chld_status));
416
+				else if (WIFSIGNALED(chld_status)) {
417
+					LOG(L_INFO, "child process %d exited by a signal"
418
+							" %d\n", chld, WTERMSIG(chld_status));
419
+#ifdef WCOREDUMP
420
+					LOG(L_INFO, "core was %sgenerated\n",
421
+							 WCOREDUMP(chld_status) ?  "" : "not" );
422
+#endif
423
+				}else if (WIFSTOPPED(chld_status)) 
424
+					LOG(L_INFO, "child process %d stopped by a"
425
+								" signal %d\n", chld,
426
+								 WSTOPSIG(chld_status));
427
+			}
428
+			/* exit */
429
+			kill(0, SIGTERM);
430
+			DBG("terminating due to SIGCHLD\n");
431
+			exit(0);
432
+			break;
433
+		
434
+		case SIGHUP: /* ignoring it*/
435
+					DBG("SIGHUP received, ignoring it\n");
436
+					break;
437
+		default:
438
+			LOG(L_CRIT, "WARNING: unhandled signal %d\n", sig_flag);
439
+	}
440
+	sig_flag=0;
441
+}
442
+
443
+
444
+
358 445
 /* main loop */
359 446
 int main_loop()
360 447
 {
... ...
@@ -458,21 +545,33 @@ int main_loop()
458 545
 	pids[process_no]=getpid();
459 546
 	process_bit = 0;
460 547
 	is_main=1;
461
-	bind_address=&sock_info[0]; /* main proc -> it shoudln't send anything, if it does */
462
-	bind_idx=0;					/*   it will use the first address */
548
+	bind_address=&sock_info[0]; /* main proc -> it shoudln't send anything, */
549
+	bind_idx=0;					/* if it does it will use the first address */
463 550
 
464 551
 	if (timer_list){
465
-		for(;;){
466
-			/* debug:  instead of doing something usefull */
467
-			/* (placeholder for timers, etc.) */
468
-			sleep(TIMER_TICK);
469
-			/* if we received a signal => TIMER_TICK may have not elapsed*/
470
-			timer_ticker();
552
+		/* fork again for the attendant process*/
553
+		if ((pid=fork())<0){
554
+			LOG(L_CRIT, "main_loop: cannot fork timer process\n");
555
+			goto error;
556
+		}else if (pid==0){
557
+			/* child */
558
+			is_main=0; /* warning: we don't keep this process pid*/
559
+			for(;;){
560
+				/* debug:  instead of doing something usefull */
561
+				/* (placeholder for timers, etc.) */
562
+				sleep(TIMER_TICK);
563
+				/* if we received a signal => TIMER_TICK may have not elapsed*/
564
+				timer_ticker();
565
+			}
471 566
 		}
472
-	}else{
473
-		for(;;) pause(); 
474 567
 	}
475 568
 	
569
+	for(;;){
570
+			pause();
571
+			handle_sigs();
572
+	}
573
+	
574
+	
476 575
 	/*return 0; */
477 576
  error:
478 577
 	return -1;
... ...
@@ -483,94 +582,41 @@ int main_loop()
483 582
 /* added by jku; allows for regular exit on a specific signal;
484 583
    good for profiling which only works if exited regularly and
485 584
    not by default signal handlers
585
+    - modified by andrei: moved most of the stuff to handle_sigs, 
586
+       made it safer for the "fork" case
486 587
 */
487 588
 static void sig_usr(int signo)
488 589
 {
489
-	pid_t	chld;
490
-	int	chld_status;
491 590
 
492
-	/* XXX Need to doublecheck .... handler fo SIGINT quite different
493
-	   from SIGTERM handler ... in SIGTERM_h, thinkgs such as
494
-	   destroy_modules and shm_destroy are missing ... is that really ok?
495
-	   THX -Jiri
496
-	*/
497
-	if (signo==SIGINT || signo==SIGPIPE) {	/* exit gracefuly */
498
-		DPrint("INT received, program terminates\n");
499
-#		ifdef _OBSOLETED_STATS
500
-		/* print statistics on exit only for the first process */
501
-		if (stats->process_index==0 && stat_file )
502
-			if (dump_all_statistic()==0)
503
-				printf("statistic dumped to %s\n", stat_file );
504
-			else
505
-				printf("statistics dump to %s failed\n", stat_file );
506
-#		endif
507
-		/* WARNING: very dangerous, might be unsafe*/
508
-		if (is_main)
509
-			destroy_modules();
510
-#ifdef PKG_MALLOC
511
-		LOG(L_INFO, "Memory status (pkg):\n");
512
-		pkg_status();
513
-#		endif
514
-#ifdef SHM_MEM
515
-		if (is_main){
516
-			LOG(L_INFO, "Memory status (shm):\n");
517
-			shm_status();
518
-			/*zero all shmem  alloc vars, that will still use*/
519
-			pids=0;
520
-			shm_mem_destroy();
521
-		}
522
-#endif
523
-		dprint("Thank you for flying " NAME "\n");
524
-		/* kill children also*/
525
-		kill(0, SIGTERM);
526
-		exit(0);
527
-	} else if (signo==SIGTERM) { /* exit gracefully as daemon */
528
-		DPrint("TERM received, program terminates\n");
529
-		if (is_main){
530
-#ifdef _OBSOLETED_STATS
531
-			dump_all_statistic();
532
-#endif
533
-			if (pid_file) {
534
-				unlink(pid_file);
535
-			}
536
-		}
537
-		kill(0, SIGTERM);
538
-		exit(0);
539
-	} else if (signo==SIGUSR1) { /* statistic */
540
-#ifdef STATS
541
-		dump_all_statistic();
542
-#endif
543
-#ifdef PKG_MALLOC
544
-		LOG(L_INFO, "Memory status (pkg):\n");
545
-		pkg_status();
546
-#endif
547
-#ifdef SHM_MEM
548
-		LOG(L_INFO, "Memory status (shm):\n");
549
-		shm_status();
550
-#endif
551
-	} else if (signo==SIGCHLD) {
552
-		while ((chld=waitpid( -1, &chld_status, WNOHANG ))>0) {
553
-			if (WIFEXITED(chld_status)) 
554
-				LOG(L_INFO, "child process %d exited normally, status=%d\n",
555
-					chld, WEXITSTATUS(chld_status));
556
-			else if (WIFSIGNALED(chld_status)) {
557
-				LOG(L_INFO, "child process %d exited by a signal %d\n",
558
-					chld, WTERMSIG(chld_status));
559
-#				ifdef WCOREDUMP
560
-				LOG(L_INFO, "core was %sgenerated\n", WCOREDUMP(chld_status) ?
561
-					"" : "not" );
562
-#				endif
563
-			} else if (WIFSTOPPED(chld_status)) 
564
-				LOG(L_INFO, "child process %d stopped by a signal %d\n",
565
-					chld, WSTOPSIG(chld_status));
591
+	if (is_main){
592
+		if (sig_flag==0) sig_flag=signo;
593
+		else /*  previous sig. not processed yet, ignoring? */
594
+			return; ;
595
+		if (dont_fork) 
596
+				/* only one proc, dooing everything from the sig handler,
597
+				unsafe, but this is only for debugging mode*/
598
+			handle_sigs();
599
+	}else{
600
+		/* process the important signals */
601
+		switch(signo){
602
+			case SIGINT:
603
+			case SIGPIPE:
604
+			case SIGTERM:
605
+					exit(0);
606
+					break;
607
+			case SIGUSR1:
608
+				/* statistics, do nothing, printed only from the main proc */
609
+					break;
610
+				/* ignored*/
611
+			case SIGUSR2:
612
+			case SIGHUP:
613
+					break;
566 614
 		}
567
-		/* exit */
568
-		kill(0, SIGTERM);
569
-		exit(0);
570 615
 	}
571 616
 }
572 617
 
573 618
 
619
+
574 620
 void test();
575 621
 
576 622
 int main(int argc, char** argv)
... ...
@@ -608,6 +654,16 @@ int main(int argc, char** argv)
608 654
 		DPrint("ERROR: no SIGTERM signal handler can be installed\n");
609 655
 		goto error;
610 656
 	}
657
+	if (signal(SIGHUP , sig_usr)  == SIG_ERR ) {
658
+		DPrint("ERROR: no SIGHUP signal handler can be installed\n");
659
+		goto error;
660
+	}
661
+	if (signal(SIGUSR2 , sig_usr)  == SIG_ERR ) {
662
+		DPrint("ERROR: no SIGUSR2 signal handler can be installed\n");
663
+		goto error;
664
+	}
665
+
666
+
611 667
 
612 668
 	/* process command line (get port no, cfg. file path etc) */
613 669
 	opterr=0;
... ...
@@ -873,8 +929,8 @@ int main(int argc, char** argv)
873 929
 						sock_info[r].port_no);
874 930
 			goto error;
875 931
 		}
876
-		/* on some system snprintf return really strange things if it does not 
877
-			have  enough space */
932
+		/* on some systems snprintf returns really strange things if it does 
933
+		  not have  enough space */
878 934
 		port_no_str_len=
879 935
 				(port_no_str_len<MAX_PORT_LEN)?port_no_str_len:MAX_PORT_LEN;
880 936
 		sock_info[r].port_no_str.s=(char*)malloc(strlen(port_no_str)+1);
... ...
@@ -8,12 +8,12 @@
8 8
 debug=9          # debug level (cmd line: -dddddddddd)
9 9
 #fork=yes          # (cmd. line: -D)
10 10
 fork=yes
11
-fork=no
11
+#fork=no
12 12
 log_stderror=yes # (cmd line: -E)
13 13
 #log_stderror=no	# (cmd line: -E)
14 14
 
15 15
 
16
-children=1
16
+children=10
17 17
 check_via=no     # (cmd. line: -v)
18 18
 dns=off           # (cmd. line: -r)
19 19
 rev_dns=off      # (cmd. line: -R)
... ...
@@ -26,6 +26,7 @@ loop_checks=0
26 26
 # for more info: sip_router -h
27 27
 
28 28
 #modules
29
+loadmodule "modules/tm/tm.so"
29 30
 
30 31
 
31 32
 route{
... ...
@@ -22,7 +22,7 @@ rev_dns=yes      # (cmd. line: -R)
22 22
 #port=5070
23 23
 #listen=127.0.0.1
24 24
 #listen=192.168.57.33
25
-listen=192.168.57.72
25
+#listen=192.168.57.72
26 26
 #listen=10.0.0.179
27 27
 loop_checks=0
28 28
 # for more info: sip_router -h