FreeBSD/usr.sbin/jail/command.c
/*
 * Check for finished processes or timeouts.
 */
Check for finished processes or timeouts.
Check for finished processes or timeouts .
struct cfjail *
next_proc(int nonblock)
{
	struct kevent ke;
	struct timespec ts;
	struct timespec *tsp;
	struct cfjail *j;
	if (!TAILQ_EMPTY(&sleeping)) {
	again:
		tsp = NULL;
		if ((j = TAILQ_FIRST(&sleeping)) && j->timeout.tv_sec) {
			clock_gettime(CLOCK_REALTIME, &ts);
			ts.tv_sec = j->timeout.tv_sec - ts.tv_sec;
			ts.tv_nsec = j->timeout.tv_nsec - ts.tv_nsec;
			if (ts.tv_nsec < 0) {
				ts.tv_sec--;
				ts.tv_nsec += 1000000000;
			}
			if (ts.tv_sec < 0 ||
			    (ts.tv_sec == 0 && ts.tv_nsec == 0)) {
				j->flags |= JF_TIMEOUT;
				clear_procs(j);
				return j;
			}
			tsp = &ts;
		}
		if (nonblock) {
			ts.tv_sec = 0;
			ts.tv_nsec = 0;
			tsp = &ts;
		}
		switch (kevent(kq, NULL, 0, &ke, 1, tsp)) {
		case -1:
			if (errno != EINTR)
				err(1, "kevent");
			goto again;
		case 0:
			if (!nonblock) {
				j = TAILQ_FIRST(&sleeping);
				j->flags |= JF_TIMEOUT;
				clear_procs(j);
				return j;
			}
			break;
		case 1:
			(void)waitpid(ke.ident, NULL, WNOHANG);
			if ((j = find_proc(ke.ident))) {
				j->pstatus = ke.data;
				return j;
			}
			goto again;
		}
	}
	return NULL;
}
struct cfjail * next_proc ( int nonblock ) { struct kevent ke ; struct timespec ts ; struct timespec * tsp ; struct cfjail * j ; if ( ! TAILQ_EMPTY ( & sleeping ) ) { again : tsp = NULL ; if ( ( j = TAILQ_FIRST ( & sleeping ) ) && j -> timeout . tv_sec ) { clock_gettime ( CLOCK_REALTIME , & ts ) ; ts . tv_sec = j -> timeout . tv_sec - ts . tv_sec ; ts . tv_nsec = j -> timeout . tv_nsec - ts . tv_nsec ; if ( ts . tv_nsec < 0 ) { ts . tv_sec -- ; ts . tv_nsec += 1000000000 ; } if ( ts . tv_sec < 0 || ( ts . tv_sec == 0 && ts . tv_nsec == 0 ) ) { j -> flags |= JF_TIMEOUT ; clear_procs ( j ) ; return j ; } tsp = & ts ; } if ( nonblock ) { ts . tv_sec = 0 ; ts . tv_nsec = 0 ; tsp = & ts ; } switch ( kevent ( kq , NULL , 0 , & ke , 1 , tsp ) ) { case -1 : if ( errno != EINTR ) err ( 1 , " " ) ; goto again ; case 0 : if ( ! nonblock ) { j = TAILQ_FIRST ( & sleeping ) ; j -> flags |= JF_TIMEOUT ; clear_procs ( j ) ; return j ; } break ; case 1 : ( void ) waitpid ( ke . ident , NULL , WNOHANG ) ; if ( ( j = find_proc ( ke . ident ) ) ) { j -> pstatus = ke . data ; return j ; } goto again ; } } return NULL ; }
Check for finished processes or timeouts.
Check for finished processes or timeouts .