Beispiel #1
0
/**
 * Exit regulary on a specific signal.
 * This is good for profiling which only works if exited regularly
 * and not by default signal handlers
 * \param signo The signal that should be handled
 */
static void sig_usr(int signo)
{
	int status;
	pid_t pid;
	UNUSED(pid);

	if (is_main){
		if (sig_flag==0) sig_flag=signo;
		else /*  previous sig. not processed yet, ignoring? */
			return; ;
		if (dont_fork)
				/* only one proc, doing everything from the sig handler,
				unsafe, but this is only for debugging mode*/
			handle_sigs();
	}else{
		/* process the important signals */
		switch(signo){
			case SIGPIPE:
					LM_INFO("signal %d received\n", signo);
				break;
			case SIGINT:
			case SIGTERM:
					LM_INFO("signal %d received\n", signo);
					/* print memory stats for non-main too */
					#ifdef PKG_MALLOC
					LM_GEN1(memdump, "Memory status (pkg):\n");
					pkg_status();
					#endif
					exit(0);
					break;
			case SIGUSR1:
					/* statistics -> show only pkg mem */
					#ifdef PKG_MALLOC
					LM_GEN1(memdump, "Memory status (pkg):\n");
					pkg_status();
					#endif
					break;
			case SIGUSR2:
					#ifdef PKG_MALLOC
					set_pkg_stats( get_pkg_status_holder(process_no) );
					#endif
					break;
			case SIGHUP:
					/* ignored*/
					break;
			case SIGCHLD:
					pid = waitpid(-1, &status, WNOHANG);
					LM_DBG("SIGCHLD received from %ld (status=%d), ignoring\n",
						(long)pid,status);
		}
	}
}
Beispiel #2
0
/**
 * Signal handler for the server.
 */
void handle_sigs(void)
{
	pid_t  chld;
	int    chld_status;
	int    i;
	int    do_exit;
	const unsigned int shutdown_time = 60; /* one minute close timeout */

	switch(sig_flag){
		case 0: break; /* do nothing*/
		case SIGPIPE:
				/* SIGPIPE might be rarely received on use of
				   exec module; simply ignore it
				 */
				LM_WARN("SIGPIPE received and ignored\n");
				break;
		case SIGINT:
		case SIGTERM:
			/* we end the program in all these cases */
			if (sig_flag==SIGINT)
				LM_DBG("INT received, program terminates\n");
			else
				LM_DBG("SIGTERM received, program terminates\n");
				
			/* first of all, kill the children also */
			kill_all_children(SIGTERM);
			if (signal(SIGALRM, sig_alarm_kill) == SIG_ERR ) {
				LM_ERR("could not install SIGALARM handler\n");
				/* continue, the process will die anyway if no
				 * alarm is installed which is exactly what we want */
			}
			alarm(shutdown_time);
			while(wait(0) > 0); /* Wait for all the children to terminate */
			signal(SIGALRM, sig_alarm_abort);

			cleanup(1); /* cleanup & show status*/
			alarm(0);
			signal(SIGALRM, SIG_IGN);
			dprint("Thank you for flying " NAME "\n");
			exit(0);
			break;
			
		case SIGUSR1:
#ifdef PKG_MALLOC
			LM_GEN1(memdump, "Memory status (pkg):\n");
			pkg_status();
#endif
#ifdef SHM_MEM
			LM_GEN1(memdump, "Memory status (shm):\n");
			shm_status();
#endif
			break;
			
		case SIGUSR2:
#ifdef PKG_MALLOC
			set_pkg_stats( get_pkg_status_holder(process_no) );
#endif
			break;
			
		case SIGCHLD:
			do_exit = 0;
			while ((chld=waitpid( -1, &chld_status, WNOHANG ))>0) {
				/* is it a process we know about? */
				for( i=0 ; i<counted_processes ; i++ )
					if (pt[i].pid==chld) break;
				if (i==counted_processes) {
					LM_DBG("unkown child process %d ended. Ignoring\n",chld);
					continue;
				}
				do_exit = 1;
				/* process the signal */
				if (WIFEXITED(chld_status)) 
					LM_INFO("child process %d exited normally,"
							" status=%d\n", chld, 
							WEXITSTATUS(chld_status));
				else if (WIFSIGNALED(chld_status)) {
					LM_INFO("child process %d exited by a signal"
							" %d\n", chld, WTERMSIG(chld_status));
#ifdef WCOREDUMP
					LM_INFO("core was %sgenerated\n",
							 WCOREDUMP(chld_status) ?  "" : "not " );
#endif
				}else if (WIFSTOPPED(chld_status)) 
					LM_INFO("child process %d stopped by a"
								" signal %d\n", chld,
								 WSTOPSIG(chld_status));
			}
			if (!do_exit)
				break;
			LM_INFO("terminating due to SIGCHLD\n");
			/* exit */
			kill_all_children(SIGTERM);
			if (signal(SIGALRM, sig_alarm_kill) == SIG_ERR ) {
				LM_ERR("could not install SIGALARM handler\n");
				/* continue, the process will die anyway if no
				 * alarm is installed which is exactly what we want */
			}
			alarm(shutdown_time);
			while(wait(0) > 0); /* wait for all the children to terminate*/
			signal(SIGALRM, sig_alarm_abort);
			cleanup(1); /* cleanup & show status*/
			alarm(0);
			signal(SIGALRM, SIG_IGN);
			LM_DBG("terminating due to SIGCHLD\n");
			exit(0);
			break;
		
		case SIGHUP: /* ignoring it*/
			LM_DBG("SIGHUP received, ignoring it\n");
			break;
		default:
			LM_CRIT("unhandled signal %d\n", sig_flag);
	}
	sig_flag=0;
}