Ejemplo n.º 1
0
static int script_run(struct script *script)
{
	sigset_t mask, old_mask;
	siginfo_t info;
	pid_t pid, *pids;
	int i, num_commands, status, ret = 0;

	for (num_commands = 0; script->commands[num_commands]; num_commands++)
		;

	if (!num_commands) {
		/* nothing to do */
		return 0;
	}

	if (create_config_files(script->configs))
		return 1;

	sigemptyset(&mask);
	sigaddset(&mask, SIGCHLD);
	sigaddset(&mask, SIGTERM);
	sigaddset(&mask, SIGQUIT);
	sigaddset(&mask, SIGINT);

	/* block the signals */
	if (sigprocmask(SIG_BLOCK, &mask, &old_mask) < 0) {
		pr_err("sigprocmask() failed: %m");
		return 1;
	}

	pids = xcalloc(num_commands, sizeof(*pids));

	for (i = 0; i < num_commands; i++) {
		pids[i] = start_program(script->commands[i], &old_mask);
		if (!pids[i]) {
			kill(getpid(), SIGTERM);
			break;
		}
	}

	/* wait for one of the blocked signals */
	while (1) {
		if (sigwaitinfo(&mask, &info) < 0) {
			if (errno == EINTR)
				continue;
			pr_err("sigwaitinfo() failed: %m");
			break;
		}

		/*
		 * assume only the first process (i.e. chronyd or ntpd) is
		 * essential and continue if other processes terminate
		 */
		if (info.si_signo == SIGCHLD && info.si_pid != pids[0]) {
			pr_info("process %d terminated (ignored)", info.si_pid);
			continue;
		}

		pr_info("received signal %d", info.si_signo);
		break;
	}

	/* kill all started processes */
	for (i = 0; i < num_commands; i++) {
		if (pids[i] > 0) {
			pr_debug("killing process %d", pids[i]);
			kill(pids[i], SIGTERM);
		}
	}

	while ((pid = wait(&status)) >= 0) {
		if (!WIFEXITED(status)) {
			pr_info("process %d terminated abnormally", pid);
			ret = 1;
		} else {
			if (WEXITSTATUS(status))
				ret = 1;
			pr_info("process %d terminated with status %d", pid,
				WEXITSTATUS(status));
		}
	}

	free(pids);

	if (remove_config_files(script->configs))
		return 1;

	return ret;
}
Ejemplo n.º 2
0
static int script_run(struct script *script)
{
	sigset_t mask, old_mask;
	siginfo_t info;
	pid_t pid, *pids;
	int i, num_commands, status, ret = 0;

	if (create_config_files(script->configs))
		return 1;

	sigemptyset(&mask);
	sigaddset(&mask, SIGCHLD);
	sigaddset(&mask, SIGTERM);
	sigaddset(&mask, SIGQUIT);
	sigaddset(&mask, SIGINT);

	/* block the signals */
	if (sigprocmask(SIG_BLOCK, &mask, &old_mask) < 0) {
		pr_err("sigprocmask() failed: %m");
		return 1;
	}

	for (num_commands = 0; script->commands[num_commands]; num_commands++)
		;

	pids = calloc(num_commands, sizeof(*pids));

	for (i = 0; i < num_commands; i++) {
		pids[i] = start_program(script->commands[i], &old_mask);
		if (!pids[i]) {
			kill(getpid(), SIGTERM);
			break;
		}
	}

	/* wait for one of the blocked signals */
	while (1) {
		if (sigwaitinfo(&mask, &info) > 0)
			break;
		if (errno != EINTR) {
			pr_err("sigwaitinfo() failed: %m");
			break;
		}
	}

	pr_info("received signal %d", info.si_signo);

	/* kill all started processes */
	for (i = 0; i < num_commands; i++) {
		if (pids[i] > 0) {
			pr_debug("killing process %d", pids[i]);
			kill(pids[i], SIGTERM);
		}
	}

	while ((pid = wait(&status)) >= 0) {
		if (!WIFEXITED(status)) {
			pr_info("process %d terminated abnormally", pid);
			ret = 1;
		} else {
			if (WEXITSTATUS(status))
				ret = 1;
			pr_info("process %d terminated with status %d", pid,
				WEXITSTATUS(status));
		}
	}

	free(pids);

	if (remove_config_files(script->configs))
		return 1;

	return ret;
}