diff options
author | Damien Miller <djm@mindrot.org> | 2001-10-12 11:35:04 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2001-10-12 11:35:04 +1000 |
commit | 3ec2759ad40f054c152c753db046ac55f9670d14 (patch) | |
tree | 3b26532eed14eaf485834a531a4d187cde1b1149 /serverloop.c | |
parent | 4e088e4de02b6c813b498a1270df85e8136c4499 (diff) |
- (djm) OpenBSD CVS Sync
- markus@cvs.openbsd.org 2001/10/10 22:18:47
[channels.c channels.h clientloop.c nchan.c serverloop.c]
[session.c session.h]
try to keep channels open until an exit-status message is sent.
don't kill the login shells if the shells stdin/out/err is closed.
this should now work:
ssh -2n localhost 'exec > /dev/null 2>&1; sleep 10; exit 5'; echo ?
Diffstat (limited to 'serverloop.c')
-rw-r--r-- | serverloop.c | 57 |
1 files changed, 29 insertions, 28 deletions
diff --git a/serverloop.c b/serverloop.c index 8a82af55b..983fe7443 100644 --- a/serverloop.c +++ b/serverloop.c | |||
@@ -35,7 +35,7 @@ | |||
35 | */ | 35 | */ |
36 | 36 | ||
37 | #include "includes.h" | 37 | #include "includes.h" |
38 | RCSID("$OpenBSD: serverloop.c,v 1.81 2001/10/09 21:59:41 markus Exp $"); | 38 | RCSID("$OpenBSD: serverloop.c,v 1.82 2001/10/10 22:18:47 markus Exp $"); |
39 | 39 | ||
40 | #include "xmalloc.h" | 40 | #include "xmalloc.h" |
41 | #include "packet.h" | 41 | #include "packet.h" |
@@ -208,9 +208,6 @@ wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp, | |||
208 | max_time_milliseconds = options.client_alive_interval * 1000; | 208 | max_time_milliseconds = options.client_alive_interval * 1000; |
209 | } | 209 | } |
210 | 210 | ||
211 | /* When select fails we restart from here. */ | ||
212 | retry_select: | ||
213 | |||
214 | /* Allocate and update select() masks for channel descriptors. */ | 211 | /* Allocate and update select() masks for channel descriptors. */ |
215 | channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, 0); | 212 | channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, 0); |
216 | 213 | ||
@@ -275,12 +272,11 @@ retry_select: | |||
275 | ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp); | 272 | ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp); |
276 | 273 | ||
277 | if (ret == -1) { | 274 | if (ret == -1) { |
275 | memset(*readsetp, 0, *maxfdp); | ||
276 | memset(*writesetp, 0, *maxfdp); | ||
278 | if (errno != EINTR) | 277 | if (errno != EINTR) |
279 | error("select: %.100s", strerror(errno)); | 278 | error("select: %.100s", strerror(errno)); |
280 | else | 279 | } else if (ret == 0 && client_alive_scheduled) |
281 | goto retry_select; | ||
282 | } | ||
283 | if (ret == 0 && client_alive_scheduled) | ||
284 | client_alive_check(); | 280 | client_alive_check(); |
285 | } | 281 | } |
286 | 282 | ||
@@ -668,13 +664,30 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) | |||
668 | /* NOTREACHED */ | 664 | /* NOTREACHED */ |
669 | } | 665 | } |
670 | 666 | ||
667 | static void | ||
668 | collect_children(void) | ||
669 | { | ||
670 | pid_t pid; | ||
671 | sigset_t oset, nset; | ||
672 | int status; | ||
673 | |||
674 | /* block SIGCHLD while we check for dead children */ | ||
675 | sigemptyset(&nset); | ||
676 | sigaddset(&nset, SIGCHLD); | ||
677 | sigprocmask(SIG_BLOCK, &nset, &oset); | ||
678 | if (child_terminated) { | ||
679 | while ((pid = waitpid(-1, &status, WNOHANG)) > 0) | ||
680 | session_close_by_pid(pid, status); | ||
681 | child_terminated = 0; | ||
682 | } | ||
683 | sigprocmask(SIG_SETMASK, &oset, NULL); | ||
684 | } | ||
685 | |||
671 | void | 686 | void |
672 | server_loop2(Authctxt *authctxt) | 687 | server_loop2(Authctxt *authctxt) |
673 | { | 688 | { |
674 | fd_set *readset = NULL, *writeset = NULL; | 689 | fd_set *readset = NULL, *writeset = NULL; |
675 | int rekeying = 0, max_fd, status, nalloc = 0; | 690 | int rekeying = 0, max_fd, nalloc = 0; |
676 | pid_t pid; | ||
677 | sigset_t oset, nset; | ||
678 | 691 | ||
679 | debug("Entering interactive session for SSH2."); | 692 | debug("Entering interactive session for SSH2."); |
680 | 693 | ||
@@ -698,16 +711,7 @@ server_loop2(Authctxt *authctxt) | |||
698 | wait_until_can_do_something(&readset, &writeset, &max_fd, | 711 | wait_until_can_do_something(&readset, &writeset, &max_fd, |
699 | &nalloc, 0); | 712 | &nalloc, 0); |
700 | 713 | ||
701 | /* block SIGCHLD while we check for dead children */ | 714 | collect_children(); |
702 | sigemptyset(&nset); | ||
703 | sigaddset(&nset, SIGCHLD); | ||
704 | sigprocmask(SIG_BLOCK, &nset, &oset); | ||
705 | if (child_terminated) { | ||
706 | while ((pid = waitpid(-1, &status, WNOHANG)) > 0) | ||
707 | session_close_by_pid(pid, status); | ||
708 | child_terminated = 0; | ||
709 | } | ||
710 | sigprocmask(SIG_SETMASK, &oset, NULL); | ||
711 | if (!rekeying) | 715 | if (!rekeying) |
712 | channel_after_select(readset, writeset); | 716 | channel_after_select(readset, writeset); |
713 | process_input(readset); | 717 | process_input(readset); |
@@ -715,6 +719,8 @@ server_loop2(Authctxt *authctxt) | |||
715 | break; | 719 | break; |
716 | process_output(writeset); | 720 | process_output(writeset); |
717 | } | 721 | } |
722 | collect_children(); | ||
723 | |||
718 | if (readset) | 724 | if (readset) |
719 | xfree(readset); | 725 | xfree(readset); |
720 | if (writeset) | 726 | if (writeset) |
@@ -723,13 +729,8 @@ server_loop2(Authctxt *authctxt) | |||
723 | /* free all channels, no more reads and writes */ | 729 | /* free all channels, no more reads and writes */ |
724 | channel_free_all(); | 730 | channel_free_all(); |
725 | 731 | ||
726 | /* collect remaining dead children, XXX not necessary? */ | 732 | /* free remaining sessions, e.g. remove wtmp entries */ |
727 | mysignal(SIGCHLD, SIG_DFL); | 733 | session_destroy_all(); |
728 | while ((pid = waitpid(-1, &status, WNOHANG)) > 0) | ||
729 | session_close_by_pid(pid, status); | ||
730 | |||
731 | /* close remaining sessions, e.g remove wtmp entries */ | ||
732 | session_close_all(); | ||
733 | } | 734 | } |
734 | 735 | ||
735 | static void | 736 | static void |