]> git.pond.sub.org Git - empserver/commitdiff
Fix client's command abort feature
authorMarkus Armbruster <armbru@pond.sub.org>
Fri, 2 Apr 2010 16:22:52 +0000 (18:22 +0200)
committerMarkus Armbruster <armbru@pond.sub.org>
Fri, 2 Apr 2010 16:22:52 +0000 (18:22 +0200)
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

index 19c46e70f289254408fbe2fdab7a9175b6715b2a..c8948591cf01d65414d2a8ec8139a5be8e6d6b46 100644 (file)
@@ -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 */