comments? allows % ssh host 'tail -f /var/log/messages | grep bla' ^C Index: clientloop.c ==================================================================RCS file: /cvs/src/usr.bin/ssh/clientloop.c,v retrieving revision 1.86 diff -u -r1.86 clientloop.c --- clientloop.c 24 Oct 2001 19:57:40 -0000 1.86 +++ clientloop.c 29 Oct 2001 19:08:37 -0000 @@ -103,6 +103,8 @@ */ static volatile int received_window_change_signal = 0; static volatile int received_signal = 0; +/* send signal to remote program: 0 disabled, 1 enabled, 2 pending */ +static volatile int 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.108 diff -u -r1.108 session.c --- session.c 11 Oct 2001 13:45:21 -0000 1.108 +++ session.c 29 Oct 2001 19:25:44 -0000 @@ -1383,6 +1383,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) { @@ -1427,6 +1468,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) {