diff options
author | djm <djm> | 2001-10-10 05:14:37 +0000 |
---|---|---|
committer | djm <djm> | 2001-10-10 05:14:37 +0000 |
commit | 827a71f5a7ec7faf88522e8567fab6420f6f0c46 (patch) | |
tree | f29ba4e7a665a6aa5d6e4ad926d7d164f7931696 /serverloop.c | |
parent | d53162015026ce26c59d8958b00872a5c71a0b8b (diff) | |
download | openssh-827a71f5a7ec7faf88522e8567fab6420f6f0c46.tar.gz |
- markus@cvs.openbsd.org 2001/10/09 21:59:41
[channels.c channels.h serverloop.c session.c session.h]
simplify session close: no more delayed session_close, no more blocking wait() calls.
Diffstat (limited to 'serverloop.c')
-rw-r--r-- | serverloop.c | 38 |
1 files changed, 15 insertions, 23 deletions
diff --git a/serverloop.c b/serverloop.c index d7282fe2..8a82af55 100644 --- a/serverloop.c +++ b/serverloop.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: serverloop.c,v 1.80 2001/10/09 19:51:18 markus Exp $"); +RCSID("$OpenBSD: serverloop.c,v 1.81 2001/10/09 21:59:41 markus Exp $"); #include "xmalloc.h" #include "packet.h" @@ -674,6 +674,7 @@ server_loop2(Authctxt *authctxt) fd_set *readset = NULL, *writeset = NULL; int rekeying = 0, max_fd, status, nalloc = 0; pid_t pid; + sigset_t oset, nset; debug("Entering interactive session for SSH2."); @@ -696,12 +697,17 @@ server_loop2(Authctxt *authctxt) channel_output_poll(); wait_until_can_do_something(&readset, &writeset, &max_fd, &nalloc, 0); + + /* block SIGCHLD while we check for dead children */ + sigemptyset(&nset); + sigaddset(&nset, SIGCHLD); + sigprocmask(SIG_BLOCK, &nset, &oset); if (child_terminated) { while ((pid = waitpid(-1, &status, WNOHANG)) > 0) session_close_by_pid(pid, status); - /* XXX race */ child_terminated = 0; } + sigprocmask(SIG_SETMASK, &oset, NULL); if (!rekeying) channel_after_select(readset, writeset); process_input(readset); @@ -709,35 +715,21 @@ server_loop2(Authctxt *authctxt) break; process_output(writeset); } - /* close all channels, no more reads and writes */ - channel_close_all(); - if (readset) xfree(readset); if (writeset) xfree(writeset); - mysignal(SIGCHLD, SIG_DFL); + /* free all channels, no more reads and writes */ + channel_free_all(); - /* collect dead children */ + /* collect remaining dead children, XXX not necessary? */ + mysignal(SIGCHLD, SIG_DFL); while ((pid = waitpid(-1, &status, WNOHANG)) > 0) session_close_by_pid(pid, status); - /* - * there is a race between channel_detach_all() killing remaining - * children and children dying before kill() - */ - channel_detach_all(); - - while (session_have_children()) { - pid = waitpid(-1, &status, 0); - if (pid > 0) - session_close_by_pid(pid, status); - else { - error("waitpid returned %d: %s", pid, strerror(errno)); - break; - } - } - channel_free_all(); + + /* close remaining sessions, e.g remove wtmp entries */ + session_close_all(); } static void |