From 4983d5ebd50800edd3c7caa08a37a5206221441d Mon Sep 17 00:00:00 2001 From: Ben Lindstrom Date: Wed, 4 Jul 2001 05:17:40 +0000 Subject: - 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 --- ChangeLog | 6 +++++- serverloop.c | 20 +++++++++++++++++--- session.c | 18 +++++++++++++++++- session.h | 3 ++- 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0a1537800..13b087d5a 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 ecc7763a4..773292a94 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 818f3211b..04b940721 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 fd91ac17c..a04fa6f2b 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 -- cgit v1.2.3