diff options
| -rw-r--r-- | scan.c | 101 | 
1 files changed, 29 insertions, 72 deletions
@@ -24,9 +24,6 @@  const char supdir[] = "/home/marius/r/svc";  char *super_path[] = { "/home/marius/r/supervise", NULL, NULL }; -volatile sig_atomic_t wait_for_child = 0; /* Do we have to call wait in the main loop? */ -volatile sig_atomic_t terminate = 0; /* Exit the main-loop */ -  struct svc {  	char dir[MAXNAMLEN + 1];  	pid_t supervisor; @@ -106,6 +103,8 @@ start_supervisor(struct svc *service)  	pid_t p = fork();  	if (p == 0) { /* Child */ +		setsid(); +  		super_path[1] = path;  		if (execv(super_path[0], super_path)) @@ -167,58 +166,6 @@ scan_svcdir(int dir_fd)  }  void -handle_sigchild(int sig, siginfo_t *siginfo, void *ucontext) -{ -	wait_for_child = 1; -} - -void -handle_fatal(int sig, siginfo_t *siginfo, void *ucontext) -{ -	terminate = 1; -} - -void -setup_signals() -{ -	struct sigaction act; -	memset(&act, 0, sizeof(act)); - -	act.sa_flags = SA_SIGINFO; - -	act.sa_sigaction = &handle_sigchild; -	if (sigaction(SIGCHLD, &act, NULL) == -1) -		err(1, "sigaction()"); - -	act.sa_sigaction = &handle_fatal; -	if (sigaction(SIGHUP, &act, NULL) == -1) -		err(1, "sigaction()"); -	if (sigaction(SIGINT, &act, NULL) == -1) -		err(1, "sigaction()"); -	if (sigaction(SIGTERM, &act, NULL) == -1) -		err(1, "sigaction()"); -} - -void -reset_signals() -{ -	struct sigaction act; -	memset(&act, 0, sizeof(act)); - -	act.sa_handler = SIG_DFL; - -	if (sigaction(SIGCHLD, &act, NULL) == -1) -		err(1, "sigaction()"); - -	if (sigaction(SIGHUP, &act, NULL) == -1) -		err(1, "sigaction()"); -	if (sigaction(SIGINT, &act, NULL) == -1) -		err(1, "sigaction()"); -	if (sigaction(SIGTERM, &act, NULL) == -1) -		err(1, "sigaction()"); -} - -void  reap_all()  {  	int r; @@ -378,7 +325,7 @@ int  main(int argc, char **argv)  {  	int kq, dir_fd, lock_fd; -	struct kevent evt; +	struct kevent evt[3];  	pid_t mypid = getpid();  	lock_fd = acquire_lock(); @@ -390,32 +337,44 @@ main(int argc, char **argv)  	if (dir_fd == -1)  		err(1, "open()"); -	setup_signals(); -  	scan_svcdir(dir_fd);  	kq = kqueue();  	if (kq == -1)  		err(1, "kqueue()"); -	EV_SET(&evt, dir_fd, EVFILT_VNODE, EV_ADD | EV_ENABLE, NOTE_WRITE | NOTE_EXTEND, 0, 0); - -	for (;;) { -		try_wait(); +	EV_SET(&evt[0], dir_fd, EVFILT_VNODE, EV_ADD | EV_ENABLE, NOTE_WRITE | NOTE_EXTEND, 0, 0); +	EV_SET(&evt[1], SIGCHLD, EVFILT_SIGNAL, EV_ADD | EV_ENABLE, 0, 0, 0); +	EV_SET(&evt[2], 1, EVFILT_TIMER, EV_ADD | EV_ENABLE | EV_ONESHOT, NOTE_SECONDS, 5, 0); -		if (terminate) { -			signal_services(SIGTERM); /* XXX: Forward the received signal? */ -			break; -		} +	if (kevent(kq, evt, 2, NULL, 0, NULL) == -1) +		err(1, "kevent()"); -		struct kevent revt; -		int e = kevent(kq, &evt, 1, &revt, 1, NULL); +	for (;;) { +		struct kevent revt[3]; +		int e = kevent(kq, NULL, 0, revt, 3, NULL);  		if (e == -1) {  			if (errno != EINTR)  				err(1, "kevent()"); -		} else if (e > 0) /* XXX: Check revt instead of blindly scanning? */ -			scan_svcdir(dir_fd); +		} else if (e > 0) { +			int i; +			for (i = 0; i < e; e++) { +				if (revt[i].filter == EVFILT_VNODE && revt[i].ident == dir_fd) { +					scan_svcdir(dir_fd); +				} else if (revt[i].filter == EVFILT_SIGNAL && revt[i].ident == SIGCHLD) { +					if (revt[i].ident == SIGCHLD) +						try_wait(); +					else if (revt[i].ident == SIGHUP || revt[i].ident == SIGINT || revt[i].ident == SIGTERM) +						goto end; +				} else if (revt[i].filter == EVFILT_TIMER && revt[i].ident == 1) { +					continue; /* XXX: start missing procs here */ +				} +			} +		}  	} + +end: +	signal_services(SIGTERM);  	if (close(kq) == -1)  		perror("close()"); @@ -424,8 +383,6 @@ main(int argc, char **argv)  	if (close(lock_fd) == -1)  		perror("close()"); -	reset_signals(); /* Make SIGTERM/INT work again in case reap_all uses a long time. */ -  	reap_all();  	return 0;  | 
