summaryrefslogtreecommitdiff
path: root/serverloop.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2001-10-12 11:35:04 +1000
committerDamien Miller <djm@mindrot.org>2001-10-12 11:35:04 +1000
commit3ec2759ad40f054c152c753db046ac55f9670d14 (patch)
tree3b26532eed14eaf485834a531a4d187cde1b1149 /serverloop.c
parent4e088e4de02b6c813b498a1270df85e8136c4499 (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.c57
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"
38RCSID("$OpenBSD: serverloop.c,v 1.81 2001/10/09 21:59:41 markus Exp $"); 38RCSID("$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. */
212retry_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
667static void
668collect_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
671void 686void
672server_loop2(Authctxt *authctxt) 687server_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
735static void 736static void