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.
This commit is contained in:
parent
6c639f1481
commit
3cceb59bb1
1 changed files with 10 additions and 5 deletions
|
@ -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 */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue