From 3cceb59bb1489de7fa1aa11a1f0a35a5490204f2 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Fri, 2 Apr 2010 18:22:52 +0200 Subject: [PATCH] Fix client's command abort feature The server aborts the current command when it receives a special line of input for a prompt. To make the client send it, you type the INTR character (normally ^C). This sends the client the SIGINT signal. Unfortunately, it never quite worked. Because we use a special line of input to signal interrupt, the client can do that only after a complete line of input. What if SIGINT arrives in the middle of a line? We split the line in two then and there, by inserting a newline. Nasty, but it's simple, and happens rarely. However, we inserted the newline always, even after a complete line. In that case, we inserted an empty line of input before the interrupt. If you hit INTR at a server prompt, the server received an empty line of input for that prompt, and the interrupt only for the *next* prompt. Which may well be too late to abort the command you wanted to abort. Fix by inserting the newline only when needed. --- src/client/play.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/client/play.c b/src/client/play.c index 19c46e70f..c8948591c 100644 --- a/src/client/play.c +++ b/src/client/play.c @@ -302,7 +302,7 @@ w32_ring_from_file_or_bounce_buf(struct ring *r, int fd) #endif #define EOF_COOKIE "ctld\n" -#define INTR_COOKIE "\naborted\n" +#define INTR_COOKIE "aborted\n" int input_fd; int send_eof; /* need to send EOF_COOKIE */ @@ -465,6 +465,7 @@ play(int sock) struct sigaction sa; struct ring inbuf; /* input buffer, draining to SOCK */ int eof_fd0; /* read fd 0 hit EOF? */ + int input_eol; /* input ends with '\n'? */ fd_set rdfd, wrfd; int n; @@ -476,7 +477,7 @@ play(int sock) sigaction(SIGPIPE, &sa, NULL); ring_init(&inbuf); - eof_fd0 = send_eof = send_intr = 0; + eof_fd0 = input_eol = send_eof = send_intr = 0; input_fd = 0; sysdep_stdin_init(); @@ -505,10 +506,13 @@ play(int sock) } } - if (send_eof + if ((send_eof || send_intr) && !input_eol + && ring_putc(&inbuf, '\n') != EOF) + input_eol = 1; + if (send_eof && input_eol && ring_putm(&inbuf, EOF_COOKIE, sizeof(EOF_COOKIE) - 1) >= 0) send_eof--; - if (send_intr + if (send_intr && input_eol && ring_putm(&inbuf, INTR_COOKIE, sizeof(INTR_COOKIE) - 1) >= 0) { send_intr = 0; if (input_fd) { @@ -542,7 +546,8 @@ play(int sock) sa.sa_handler = SIG_DFL; sigaction(SIGINT, &sa, NULL); } - } + } else + input_eol = ring_peek(&inbuf, -1) == '\n'; } /* send it to the server */ -- 2.43.0