... | ... |
@@ -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{ |