summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--clientloop.c40
-rw-r--r--serverloop.c55
-rw-r--r--sshd.c23
4 files changed, 50 insertions, 74 deletions
diff --git a/ChangeLog b/ChangeLog
index ba70812f..84538fe6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -39,6 +39,10 @@
[channels.c channels.h session.c]
switch uid when cleaning up tmp files and sockets; reported by
zen-parse@gmx.net on bugtraq
+ - markus@cvs.openbsd.org 2001/06/04 23:07:21
+ [clientloop.c serverloop.c sshd.c]
+ set flags in the signal handlers, do real work in the main loop,
+ ok provos@
20010606
- OpenBSD CVS Sync
@@ -5550,4 +5554,4 @@
- Wrote replacements for strlcpy and mkdtemp
- Released 1.0pre1
-$Id: ChangeLog,v 1.1258 2001/06/09 01:20:06 mouring Exp $
+$Id: ChangeLog,v 1.1259 2001/06/09 01:27:31 mouring Exp $
diff --git a/clientloop.c b/clientloop.c
index 70abee8f..3a1b43dd 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -59,7 +59,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: clientloop.c,v 1.74 2001/05/31 10:30:15 markus Exp $");
+RCSID("$OpenBSD: clientloop.c,v 1.75 2001/06/04 23:07:20 markus Exp $");
#include "ssh.h"
#include "ssh1.h"
@@ -102,6 +102,7 @@ extern char *host;
* because this is updated in a signal handler.
*/
static volatile int received_window_change_signal = 0;
+static volatile int received_signal = 0;
/* Flag indicating whether the user\'s terminal is in non-blocking mode. */
static int in_non_blocking_mode = 0;
@@ -171,13 +172,8 @@ window_change_handler(int sig)
void
signal_handler(int sig)
{
- if (in_raw_mode())
- leave_raw_mode();
- if (in_non_blocking_mode)
- leave_non_blocking();
- channel_stop_listening();
- packet_close();
- fatal("Killed by signal %d.", sig);
+ received_signal = sig;
+ quit_pending = 1;
}
/*
@@ -933,14 +929,8 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
/* Stop listening for connections. */
channel_stop_listening();
- /*
- * In interactive mode (with pseudo tty) display a message indicating
- * that the connection has been closed.
- */
- if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) {
- snprintf(buf, sizeof buf, "Connection to %.64s closed.\r\n", host);
- buffer_append(&stderr_buffer, buf, strlen(buf));
- }
+ if (have_pty)
+ leave_raw_mode();
/* restore blocking io */
if (!isatty(fileno(stdin)))
@@ -950,6 +940,21 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
if (!isatty(fileno(stderr)))
unset_nonblock(fileno(stderr));
+ if (received_signal) {
+ if (in_non_blocking_mode) /* XXX */
+ leave_non_blocking();
+ fatal("Killed by signal %d.", received_signal);
+ }
+
+ /*
+ * In interactive mode (with pseudo tty) display a message indicating
+ * that the connection has been closed.
+ */
+ if (have_pty && options.log_level != SYSLOG_LEVEL_QUIET) {
+ snprintf(buf, sizeof buf, "Connection to %.64s closed.\r\n", host);
+ buffer_append(&stderr_buffer, buf, strlen(buf));
+ }
+
/* Output any buffered data for stdout. */
while (buffer_len(&stdout_buffer) > 0) {
len = write(fileno(stdout), buffer_ptr(&stdout_buffer),
@@ -974,9 +979,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
stderr_bytes += len;
}
- if (have_pty)
- leave_raw_mode();
-
/* Clear and free any buffers. */
memset(buf, 0, sizeof(buf));
buffer_free(&stdin_buffer);
diff --git a/serverloop.c b/serverloop.c
index d8026ec5..bafbfb0a 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -35,7 +35,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: serverloop.c,v 1.67 2001/05/31 10:30:16 markus Exp $");
+RCSID("$OpenBSD: serverloop.c,v 1.68 2001/06/04 23:07:20 markus Exp $");
#include "xmalloc.h"
#include "packet.h"
@@ -84,10 +84,7 @@ static u_int buffer_high; /* "Soft" max buffer size. */
* This SIGCHLD kludge is used to detect when the child exits. The server
* will exit after that, as soon as forwarded connections have terminated.
*/
-
-static pid_t child_pid; /* Pid of the child. */
static volatile int child_terminated; /* The child has terminated. */
-static volatile int child_wait_status; /* Status from wait(). */
void server_init_dispatch(void);
@@ -97,28 +94,9 @@ void
sigchld_handler(int sig)
{
int save_errno = errno;
- pid_t wait_pid;
-
- debug("Received SIGCHLD.");
- wait_pid = wait((int *) &child_wait_status);
- if (wait_pid != -1) {
- if (wait_pid != child_pid)
- error("Strange, got SIGCHLD and wait returned pid %d but child is %d",
- wait_pid, child_pid);
- if (WIFEXITED(child_wait_status) ||
- WIFSIGNALED(child_wait_status))
- child_terminated = 1;
- }
- signal(SIGCHLD, sigchld_handler);
- errno = save_errno;
-}
-void
-sigchld_handler2(int sig)
-{
- int save_errno = errno;
debug("Received SIGCHLD.");
child_terminated = 1;
- mysignal(SIGCHLD, sigchld_handler2);
+ mysignal(SIGCHLD, sigchld_handler);
errno = save_errno;
}
@@ -466,7 +444,6 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
debug("Entering interactive session.");
/* Initialize the SIGCHLD kludge. */
- child_pid = pid;
child_terminated = 0;
signal(SIGCHLD, sigchld_handler);
@@ -634,28 +611,16 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
/* Stop listening for channels; this removes unix domain sockets. */
channel_stop_listening();
- /* Wait for the child to exit. Get its exit status. */
- wait_pid = wait(&wait_status);
- if (wait_pid == -1) {
- /*
- * It is possible that the wait was handled by SIGCHLD
- * handler. This may result in either: this call
- * returning with EINTR, or: this call returning ECHILD.
- */
- if (child_terminated)
- wait_status = child_wait_status;
- else
- packet_disconnect("wait: %.100s", strerror(errno));
- } else {
- /* Check if it matches the process we forked. */
- if (wait_pid != pid)
- error("Strange, wait returned pid %d, expected %d",
- wait_pid, pid);
- }
-
/* We no longer want our SIGCHLD handler to be called. */
signal(SIGCHLD, SIG_DFL);
+ wait_pid = waitpid(-1, &wait_status, child_terminated ? WNOHANG : 0);
+ if (wait_pid == -1)
+ packet_disconnect("wait: %.100s", strerror(errno));
+ else if (wait_pid != pid)
+ error("Strange, wait returned pid %d, expected %d",
+ wait_pid, pid);
+
/* Check if it exited normally. */
if (WIFEXITED(wait_status)) {
/* Yes, normal exit. Get exit status and send it to the client. */
@@ -700,7 +665,7 @@ server_loop2(void)
debug("Entering interactive session for SSH2.");
- mysignal(SIGCHLD, sigchld_handler2);
+ mysignal(SIGCHLD, sigchld_handler);
child_terminated = 0;
connection_in = packet_get_connection_in();
connection_out = packet_get_connection_out();
diff --git a/sshd.c b/sshd.c
index 869c1201..1dfcac0d 100644
--- a/sshd.c
+++ b/sshd.c
@@ -40,7 +40,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.198 2001/05/28 23:58:35 markus Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.199 2001/06/04 23:07:21 markus Exp $");
#include <openssl/dh.h>
#include <openssl/bn.h>
@@ -167,8 +167,9 @@ struct {
*/
int key_do_regen = 0;
-/* This is set to true when SIGHUP is received. */
+/* This is set to true when a signal is received. */
int received_sighup = 0;
+int received_sigterm = 0;
/* session identifier, used by RSA-auth */
u_char session_id[16];
@@ -227,21 +228,16 @@ sighup_restart(void)
/*
* Generic signal handler for terminating signals in the master daemon.
- * These close the listen socket; not closing it seems to cause "Address
- * already in use" problems on some machines, which is inconvenient.
*/
void
sigterm_handler(int sig)
{
- log("Received signal %d; terminating.", sig);
- close_listen_socks();
- unlink(options.pid_file);
- exit(255);
+ received_sigterm = sig;
}
/*
* SIGCHLD handler. This is called whenever a child dies. This will then
- * reap any zombies left by exited c.
+ * reap any zombies left by exited children.
*/
void
main_sigchld_handler(int sig)
@@ -262,6 +258,8 @@ main_sigchld_handler(int sig)
void
grace_alarm_handler(int sig)
{
+ /* XXX no idea how fix this signal handler */
+
/* Close the connection. */
packet_close();
@@ -939,6 +937,13 @@ main(int ac, char **av)
ret = select(maxfd+1, fdset, NULL, NULL, NULL);
if (ret < 0 && errno != EINTR)
error("select: %.100s", strerror(errno));
+ if (received_sigterm) {
+ log("Received signal %d; terminating.",
+ received_sigterm);
+ close_listen_socks();
+ unlink(options.pid_file);
+ exit(255);
+ }
if (key_used && key_do_regen) {
generate_ephemeral_server_key();
key_used = 0;