signal transmission in ssh2

Markus Friedl markus at openbsd.org
Fri Feb 1 04:18:24 EST 2002


does somebody like this?


Index: Makefile.inc
===================================================================
RCS file: /cvs/src/usr.bin/ssh/Makefile.inc,v
retrieving revision 1.21
diff -u -r1.21 Makefile.inc
--- Makefile.inc	30 Oct 2001 20:32:31 -0000	1.21
+++ Makefile.inc	16 Nov 2001 12:07:22 -0000
@@ -10,7 +10,7 @@
 CDIAGFLAGS+=	-Wmissing-prototypes
 CDIAGFLAGS+=	-Wunused
 
-#DEBUG=-g
+DEBUG=-g
 
 #CFLAGS+=	-DSMARTCARD
 #LDADD+=	-lsectok
Index: clientloop.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/clientloop.c,v
retrieving revision 1.95
diff -u -r1.95 clientloop.c
--- clientloop.c	10 Jan 2002 11:24:04 -0000	1.95
+++ clientloop.c	31 Jan 2002 17:17:19 -0000
@@ -103,6 +103,8 @@
  */
 static volatile sig_atomic_t received_window_change_signal = 0;
 static volatile sig_atomic_t received_signal = 0;
+/* send signal to remote program: 0 disabled, 1 enabled, 2 pending */
+static volatile sig_atomic_t send_signal = 0;
 
 /* Flag indicating whether the user\'s terminal is in non-blocking mode. */
 static int in_non_blocking_mode = 0;
@@ -173,7 +175,10 @@
 signal_handler(int sig)
 {
 	received_signal = sig;
-	quit_pending = 1;
+	if (send_signal == 1)
+		send_signal = 2;
+	else
+		quit_pending = 1;
 }
 
 /*
@@ -765,6 +770,26 @@
 		leave_raw_mode();
 }
 
+static char *
+sig2name(int sig)
+{
+#define SIG(x) if (sig == SIG ## x) return #x
+	SIG(ABRT);
+	SIG(ALRM);
+	SIG(FPE);
+	SIG(HUP);
+	SIG(ILL);
+	SIG(INT);
+	SIG(KILL);
+	SIG(PIPE);
+	SIG(QUIT);
+	SIG(SEGV);
+	SIG(TERM);
+	SIG(USR1);
+	SIG(USR2);
+	return "";
+}
+
 /*
  * Implements the interactive session with the server.  This is called after
  * the user has been authenticated, and a command has been started on the
@@ -778,7 +803,7 @@
 	fd_set *readset = NULL, *writeset = NULL;
 	double start_time, total_time;
 	int max_fd = 0, max_fd2 = 0, len, rekeying = 0, nalloc = 0;
-	char buf[100];
+	char *signame, buf[100];
 
 	debug("Entering interactive session.");
 
@@ -819,6 +844,10 @@
 
 	client_init_dispatch();
 
+	/* for protocol v2 we try to send the signal to the remote host */
+	if (compat20 && !have_pty && ssh2_chan_id != -1)
+		send_signal = 1;
+
 	/* Set signal handlers to restore non-blocking mode.  */
 	signal(SIGINT, signal_handler);
 	signal(SIGQUIT, signal_handler);
@@ -899,6 +928,18 @@
 				xxx_kex->done = 0;
 				kex_send_kexinit(xxx_kex);
 				need_rekeying = 0;
+			}
+			if (send_signal == 2) {
+				send_signal = 0;
+				signame = sig2name(received_signal);
+				debug("Sending SIG%s to the remote host.",
+				    signame);
+				packet_start(SSH2_MSG_CHANNEL_REQUEST);
+				packet_put_int(session_ident);
+				packet_put_cstring("signal");
+				packet_put_char(0);
+				packet_put_cstring(signame);
+				packet_send();
 			}
 		}
 
Index: session.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/session.c,v
retrieving revision 1.122
diff -u -r1.122 session.c
--- session.c	29 Jan 2002 22:46:41 -0000	1.122
+++ session.c	31 Jan 2002 17:17:21 -0000
@@ -1375,6 +1375,47 @@
 	}
 }
 
+static int
+name2sig(char *name)
+{
+#define SIG(x) if (strcmp(name, #x) == 0) return SIG ## x
+	SIG(ABRT);
+	SIG(ALRM);
+	SIG(FPE);
+	SIG(HUP);
+	SIG(ILL);
+	SIG(INT);
+	SIG(KILL);
+	SIG(PIPE);
+	SIG(QUIT);
+	SIG(SEGV);
+	SIG(TERM);
+	SIG(USR1);
+	SIG(USR2);
+	return -1;
+}
+
+static int
+session_signal_req(Session *s)
+{
+	char *signame;
+	int sig;
+
+	signame = packet_get_string(NULL);
+	sig = name2sig(signame);
+	xfree(signame);
+	packet_done();
+
+	if (sig >= 0 && s->pid > 0) {
+		debug("session_signal_req: killpg(%d, %d)",
+		    s->pid, sig);
+		if (killpg(s->pid, sig) < 0)
+			error("session_signal_req: killpg(%d, %d): %s",
+			    s->pid, sig, strerror(errno));
+	}
+	return 0;
+}
+
 void
 session_input_channel_req(int id, void *arg)
 {
@@ -1419,6 +1460,8 @@
 	}
 	if (strcmp(rtype, "window-change") == 0) {
 		success = session_window_change_req(s);
+	} else if (strcmp(rtype, "signal") == 0) {
+		success = session_signal_req(s);
 	}
 
 	if (reply) {



More information about the openssh-unix-dev mailing list