summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormouring <mouring>2001-07-04 05:17:40 +0000
committermouring <mouring>2001-07-04 05:17:40 +0000
commitc1a8d9f3a9544eebd203553c7953a2c78d1b3e81 (patch)
tree52015f7e2297f25ca203e44be61b8b4e2aab3ce1
parentde66bfbd170b49bd83e4141f21821f070cfdf4e7 (diff)
downloadopenssh-c1a8d9f3a9544eebd203553c7953a2c78d1b3e81.tar.gz
- markus@cvs.openbsd.org 2001/07/02 13:59:15
[serverloop.c session.c session.h] wait until !session_have_children(); bugreport from Lutz.Jaenicke@aet.TU-Cottbus.DE
-rw-r--r--ChangeLog6
-rw-r--r--serverloop.c20
-rw-r--r--session.c18
-rw-r--r--session.h3
4 files changed, 41 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 0a153780..13b087d5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -114,6 +114,10 @@
- stevesk@cvs.openbsd.org 2001/06/30 18:08:40
[channels.c channels.h clientloop.c]
adress -> address; ok markus@
+ - markus@cvs.openbsd.org 2001/07/02 13:59:15
+ [serverloop.c session.c session.h]
+ wait until !session_have_children(); bugreport from
+ Lutz.Jaenicke@aet.TU-Cottbus.DE
20010629
- (bal) Removed net_aton() since we don't use it any more
@@ -5941,4 +5945,4 @@
- Wrote replacements for strlcpy and mkdtemp
- Released 1.0pre1
-$Id: ChangeLog,v 1.1372 2001/07/04 05:15:15 mouring Exp $
+$Id: ChangeLog,v 1.1373 2001/07/04 05:17:40 mouring Exp $
diff --git a/serverloop.c b/serverloop.c
index ecc7763a..773292a9 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -35,7 +35,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: serverloop.c,v 1.72 2001/06/27 02:12:52 markus Exp $");
+RCSID("$OpenBSD: serverloop.c,v 1.73 2001/07/02 13:59:14 markus Exp $");
#include "xmalloc.h"
#include "packet.h"
@@ -703,11 +703,25 @@ server_loop2(Authctxt *authctxt)
if (writeset)
xfree(writeset);
- channel_free_all();
-
signal(SIGCHLD, SIG_DFL);
+
while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
session_close_by_pid(pid, status);
+ /*
+ * there is a race between channel_free_all() killing children and
+ * children dying before kill()
+ */
+ channel_free_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;
+ }
+ }
}
static void
diff --git a/session.c b/session.c
index 818f3211..04b94072 100644
--- a/session.c
+++ b/session.c
@@ -33,7 +33,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.97 2001/06/27 02:12:53 markus Exp $");
+RCSID("$OpenBSD: session.c,v 1.98 2001/07/02 13:59:15 markus Exp $");
#include "ssh.h"
#include "ssh1.h"
@@ -1959,6 +1959,22 @@ session_close_by_pid(pid_t pid, int status)
session_close(s);
}
+int
+session_have_children(void)
+{
+ int i;
+
+ for(i = 0; i < MAX_SESSIONS; i++) {
+ Session *s = &sessions[i];
+ if (s->used && s->pid != -1) {
+ debug("session_have_children: id %d pid %d", i, s->pid);
+ return 1;
+ }
+ }
+ debug("session_have_children: no more children");
+ return 0;
+}
+
/*
* this is called when a channel dies before
* the session 'child' itself dies
diff --git a/session.h b/session.h
index fd91ac17..a04fa6f2 100644
--- a/session.h
+++ b/session.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.h,v 1.10 2001/06/27 02:12:54 markus Exp $ */
+/* $OpenBSD: session.h,v 1.11 2001/07/02 13:59:15 markus Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -32,5 +32,6 @@ int session_open(Authctxt*, int);
void session_input_channel_req(int, void *);
void session_close_by_pid(pid_t, int);
void session_close_by_channel(int, void *);
+int session_have_children(void);
#endif