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 355
 
356 356
 
357 357
 
358
+void handle_sigs()
359
+{
360
+	pid_t	chld;
361
+	int	chld_status;
362
+
363
+	switch(sig_flag){
364
+		case 0: break; /* do nothing*/
365
+		case SIGINT:
366
+		case SIGPIPE:
367
+		case SIGTERM:
368
+			/* we end the program in all these cases */
369
+			if (sig_flag==SIGINT)
370
+				DBG("INT received, program terminates\n");
371
+			else if (sig_flag==SIGPIPE)
372
+				DBG("SIGPIPE rreceived, program terminates\n");
373
+			else
374
+				DBG("SIGTERM received, program terminates\n");
375
+				
376
+			destroy_modules();
377
+#ifdef PKG_MALLOC
378
+			LOG(L_INFO, "Memory status (pkg):\n");
379
+			pkg_status();
380
+#endif
381
+#ifdef SHM_MEM
382
+			LOG(L_INFO, "Memory status (shm):\n");
383
+			shm_status();
384
+			/* zero all shmem alloc vars that we still use */
385
+			pids=0;
386
+			shm_mem_destroy();
387
+#endif
388
+			if (pid_file) unlink(pid_file);
389
+			/* kill children also*/
390
+			kill(0, SIGTERM);
391
+			dprint("Thank you for flying " NAME "\n");
392
+			exit(0);
393
+			break;
394
+			
395
+		case SIGUSR1:
396
+#ifdef STATS
397
+			dump_all_statistic();
398
+#endif
399
+#ifdef PKG_MALLOC
400
+			LOG(L_INFO, "Memory status (pkg):\n");
401
+			pkg_status();
402
+#endif
403
+#ifdef SHM_MEM
404
+			LOG(L_INFO, "Memory status (shm):\n");
405
+			shm_status();
406
+#endif
407
+			break;
408
+			
409
+		case SIGCHLD:
410
+			while ((chld=waitpid( -1, &chld_status, WNOHANG ))>0) {
411
+				if (WIFEXITED(chld_status)) 
412
+					LOG(L_INFO, "child process %d exited normally,"
413
+							" status=%d\n", chld, 
414
+							WEXITSTATUS(chld_status));
415
+				else if (WIFSIGNALED(chld_status)) {
416
+					LOG(L_INFO, "child process %d exited by a signal"
417
+							" %d\n", chld, WTERMSIG(chld_status));
418
+#ifdef WCOREDUMP
419
+					LOG(L_INFO, "core was %sgenerated\n",
420
+							 WCOREDUMP(chld_status) ?  "" : "not" );
421
+#endif
422
+				}else if (WIFSTOPPED(chld_status)) 
423
+					LOG(L_INFO, "child process %d stopped by a"
424
+								" signal %d\n", chld,
425
+								 WSTOPSIG(chld_status));
426
+			}
427
+			/* exit */
428
+			kill(0, SIGTERM);
429
+			DBG("terminating due to SIGCHLD\n");
430
+			exit(0);
431
+			break;
432
+		
433
+		case SIGHUP: /* ignoring it*/
434
+					DBG("SIGHUP received, ignoring it\n");
435
+					break;
436
+		default:
437
+			LOG(L_CRIT, "WARNING: unhandled signal %d\n", sig_flag);
438
+	}
439
+	sig_flag=0;
440
+}
441
+
442
+
443
+
358 444
 /* main loop */
359 445
 int main_loop()
360 446
 {
... ...
@@ -458,21 +545,33 @@ int main_loop()
458 458
 	pids[process_no]=getpid();
459 459
 	process_bit = 0;
460 460
 	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 */
461
+	bind_address=&sock_info[0]; /* main proc -> it shoudln't send anything, */
462
+	bind_idx=0;					/* if it does it will use the first address */
463 463
 
464 464
 	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();
465
+		/* fork again for the attendant process*/
466
+		if ((pid=fork())<0){
467
+			LOG(L_CRIT, "main_loop: cannot fork timer process\n");
468
+			goto error;
469
+		}else if (pid==0){
470
+			/* child */
471
+			is_main=0; /* warning: we don't keep this process pid*/
472
+			for(;;){
473
+				/* debug:  instead of doing something usefull */
474
+				/* (placeholder for timers, etc.) */
475
+				sleep(TIMER_TICK);
476
+				/* if we received a signal => TIMER_TICK may have not elapsed*/
477
+				timer_ticker();
478
+			}
471 479
 		}
472
-	}else{
473
-		for(;;) pause(); 
474 480
 	}
475 481
 	
482
+	for(;;){
483
+			pause();
484
+			handle_sigs();
485
+	}
486
+	
487
+	
476 488
 	/*return 0; */
477 489
  error:
478 490
 	return -1;
... ...
@@ -483,94 +582,41 @@ int main_loop()
483 483
 /* added by jku; allows for regular exit on a specific signal;
484 484
    good for profiling which only works if exited regularly and
485 485
    not by default signal handlers
486
+    - modified by andrei: moved most of the stuff to handle_sigs, 
487
+       made it safer for the "fork" case
486 488
 */
487 489
 static void sig_usr(int signo)
488 490
 {
489
-	pid_t	chld;
490
-	int	chld_status;
491 491
 
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));
492
+	if (is_main){
493
+		if (sig_flag==0) sig_flag=signo;
494
+		else /*  previous sig. not processed yet, ignoring? */
495
+			return; ;
496
+		if (dont_fork) 
497
+				/* only one proc, dooing everything from the sig handler,
498
+				unsafe, but this is only for debugging mode*/
499
+			handle_sigs();
500
+	}else{
501
+		/* process the important signals */
502
+		switch(signo){
503
+			case SIGINT:
504
+			case SIGPIPE:
505
+			case SIGTERM:
506
+					exit(0);
507
+					break;
508
+			case SIGUSR1:
509
+				/* statistics, do nothing, printed only from the main proc */
510
+					break;
511
+				/* ignored*/
512
+			case SIGUSR2:
513
+			case SIGHUP:
514
+					break;
566 515
 		}
567
-		/* exit */
568
-		kill(0, SIGTERM);
569
-		exit(0);
570 516
 	}
571 517
 }
572 518
 
573 519
 
520
+
574 521
 void test();
575 522
 
576 523
 int main(int argc, char** argv)
... ...
@@ -608,6 +654,16 @@ int main(int argc, char** argv)
608 608
 		DPrint("ERROR: no SIGTERM signal handler can be installed\n");
609 609
 		goto error;
610 610
 	}
611
+	if (signal(SIGHUP , sig_usr)  == SIG_ERR ) {
612
+		DPrint("ERROR: no SIGHUP signal handler can be installed\n");
613
+		goto error;
614
+	}
615
+	if (signal(SIGUSR2 , sig_usr)  == SIG_ERR ) {
616
+		DPrint("ERROR: no SIGUSR2 signal handler can be installed\n");
617
+		goto error;
618
+	}
619
+
620
+
611 621
 
612 622
 	/* process command line (get port no, cfg. file path etc) */
613 623
 	opterr=0;
... ...
@@ -873,8 +929,8 @@ int main(int argc, char** argv)
873 873
 						sock_info[r].port_no);
874 874
 			goto error;
875 875
 		}
876
-		/* on some system snprintf return really strange things if it does not 
877
-			have  enough space */
876
+		/* on some systems snprintf returns really strange things if it does 
877
+		  not have  enough space */
878 878
 		port_no_str_len=
879 879
 				(port_no_str_len<MAX_PORT_LEN)?port_no_str_len:MAX_PORT_LEN;
880 880
 		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