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