diff options
Diffstat (limited to 'usr.sbin/jail/command.c')
-rw-r--r-- | usr.sbin/jail/command.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/usr.sbin/jail/command.c b/usr.sbin/jail/command.c index b7d5168..452a079 100644 --- a/usr.sbin/jail/command.c +++ b/usr.sbin/jail/command.c @@ -66,7 +66,7 @@ int paralimit = -1; extern char **environ; static int run_command(struct cfjail *j); -static void add_proc(struct cfjail *j, pid_t pid); +static int add_proc(struct cfjail *j, pid_t pid); static void clear_procs(struct cfjail *j); static struct cfjail *find_proc(pid_t pid); static int term_procs(struct cfjail *j); @@ -88,13 +88,14 @@ int next_command(struct cfjail *j) { enum intparam comparam; - int create_failed; + int create_failed, stopping; if (paralimit == 0) { requeue(j, &runnable); return 1; } create_failed = (j->flags & (JF_STOP | JF_FAILED)) == JF_FAILED; + stopping = (j->flags & JF_STOP) != 0; comparam = *j->comparam; for (;;) { if (j->comstring == NULL) { @@ -113,14 +114,16 @@ next_command(struct cfjail *j) default: if (j->intparams[comparam] == NULL) continue; - j->comstring = create_failed + j->comstring = create_failed || (stopping && + (j->intparams[comparam]->flags & PF_REV)) ? TAILQ_LAST(&j->intparams[comparam]->val, cfstrings) : TAILQ_FIRST(&j->intparams[comparam]->val); } } else { j->comstring = j->comstring == &dummystring ? NULL : - create_failed + create_failed || (stopping && + (j->intparams[comparam]->flags & PF_REV)) ? TAILQ_PREV(j->comstring, cfstrings, tq) : TAILQ_NEXT(j->comstring, tq); } @@ -542,13 +545,12 @@ run_command(struct cfjail *j) if (pid < 0) err(1, "fork"); if (pid > 0) { - if (bg) { + if (bg || !add_proc(j, pid)) { free(j->comline); j->comline = NULL; return 0; } else { paralimit--; - add_proc(j, pid); return 1; } } @@ -622,7 +624,7 @@ run_command(struct cfjail *j) /* * Add a process to the hash, tied to a jail. */ -static void +static int add_proc(struct cfjail *j, pid_t pid) { struct kevent ke; @@ -632,8 +634,11 @@ add_proc(struct cfjail *j, pid_t pid) if (!kq && (kq = kqueue()) < 0) err(1, "kqueue"); EV_SET(&ke, pid, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, NULL); - if (kevent(kq, &ke, 1, NULL, 0, NULL) < 0) + if (kevent(kq, &ke, 1, NULL, 0, NULL) < 0) { + if (errno == ESRCH) + return 0; err(1, "kevent"); + } ph = emalloc(sizeof(struct phash)); ph->j = j; ph->pid = pid; @@ -658,6 +663,7 @@ add_proc(struct cfjail *j, pid_t pid) TAILQ_INSERT_TAIL(&sleeping, j, tq); j->queue = &sleeping; } + return 1; } /* @@ -730,7 +736,7 @@ term_procs(struct cfjail *j) for (i = 0; i < pcnt; i++) if (ki[i].ki_jid == j->jid && kill(ki[i].ki_pid, SIGTERM) == 0) { - add_proc(j, ki[i].ki_pid); + (void)add_proc(j, ki[i].ki_pid); if (verbose > 0) { if (!noted) { noted = 1; |