client: Fix obscure readline hang
If recv_input() can't stuff the whole line into @inbuf, it leaves its tail in @input_from_rl. If send_input() then empties @inbuf, the next iteration will select @input_fd for reading instead of @sock for writing, because @inbuf is empty. Since @has_rl_input is still set, recv_input() will do nothing, and the client hangs. Fix as follows. Factor ring_from_rl() out of recv_input(). Also call it in send_input() to refill @inbuf from @input_from_rl. Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
This commit is contained in:
parent
0cb6690600
commit
5e82836e3a
1 changed files with 33 additions and 15 deletions
|
@ -451,6 +451,32 @@ input_handler(char *line)
|
|||
add_history(line);
|
||||
#endif /* HAVE_READLINE_HISTORY */
|
||||
}
|
||||
|
||||
static int
|
||||
ring_from_rl(struct ring *inbuf)
|
||||
{
|
||||
size_t len;
|
||||
int n;
|
||||
|
||||
assert(has_rl_input && input_from_rl);
|
||||
|
||||
len = strlen(input_from_rl);
|
||||
n = ring_space(inbuf);
|
||||
assert(n);
|
||||
|
||||
if (len >= (size_t)n) {
|
||||
ring_putm(inbuf, input_from_rl, n);
|
||||
memmove(input_from_rl, input_from_rl + n, len - n + 1);
|
||||
} else {
|
||||
ring_putm(inbuf, input_from_rl, len);
|
||||
ring_putc(inbuf, '\n');
|
||||
free(input_from_rl);
|
||||
has_rl_input = 0;
|
||||
n = len + 1;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
#endif /* HAVE_LIBREADLINE */
|
||||
|
||||
/*
|
||||
|
@ -462,28 +488,15 @@ recv_input(int fd, struct ring *inbuf)
|
|||
{
|
||||
int n;
|
||||
int res = 1;
|
||||
#ifdef HAVE_LIBREADLINE
|
||||
size_t len;
|
||||
|
||||
#ifdef HAVE_LIBREADLINE
|
||||
if (fd == 0) {
|
||||
if (!has_rl_input)
|
||||
rl_callback_read_char();
|
||||
if (!has_rl_input)
|
||||
return 1;
|
||||
if (input_from_rl) {
|
||||
len = strlen(input_from_rl);
|
||||
n = ring_space(inbuf);
|
||||
assert(n);
|
||||
if (len >= (size_t)n) {
|
||||
ring_putm(inbuf, input_from_rl, n);
|
||||
memmove(input_from_rl, input_from_rl + n, len - n + 1);
|
||||
} else {
|
||||
ring_putm(inbuf, input_from_rl, len);
|
||||
ring_putc(inbuf, '\n');
|
||||
free(input_from_rl);
|
||||
has_rl_input = 0;
|
||||
n = len + 1;
|
||||
}
|
||||
n = ring_from_rl(inbuf);
|
||||
} else
|
||||
n = 0;
|
||||
} else
|
||||
|
@ -524,6 +537,11 @@ send_input(int fd, struct ring *inbuf)
|
|||
putc(ch, auxfp);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBREADLINE
|
||||
if (fd == 0 && has_rl_input && input_from_rl)
|
||||
ring_from_rl(inbuf);
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue