NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
lib/58955: libedit: rl_event_hook not called when output is piped to another process
>Number: 58955
>Category: lib
>Synopsis: libedit: rl_event_hook not called when output is piped to another process
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: lib-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Jan 03 00:00:00 +0000 2025
>Originator: Michael Rosen
>Release:
>Organization:
>Environment:
Linux --- 5.15.153.1-microsoft-standard-WSL2+ #11 SMP Mon Apr 29 14:24:57 PDT 2024 x86_64 x86_64 x86_64 GNU/Linux
>Description:
rl_event_hook should be called periodically if set while waiting on characters during blocking readline calls. From the documentation on GNU readline:
"If non-zero, this is the address of a function to call periodically when Readline is waiting for terminal input. By default, this will be called at most ten times a second if there is no keyboard input."
However, if the output of a program using Libedit's readline implementation is piped into another program (ie ./libedit_readline_program_using_rl_event_hook | grep "some output"), the program will not call the rl_event_hook function (which might include some important logic) and the readline call will just block, possibly forever.
The problem arises from the following condition to the rl_event_hook installation in readline (readline.c:467):
if (rl_event_hook && !(e->el_flags & NO_TTY)) {
el_set(e, EL_GETCFN, _rl_event_read_char);
used_event_hook = 1;
}
The check for NO_TTY (which if one dives into where thats set comes from tty.c:508, isatty(el->el_outfd), which is false when the output is piped to another process) is the reason the rl_event_hook will not be installed in this case.
Is there a reason the output needs to be a tty? Removing this condition seems to fix the problem but I would assume there was a reason for it to be there in the first place (no comment nor any information in the commit message for the change that introduced it, revision 1.38 of readline.c).
>How-To-Repeat:
Using this program:
#include <stdio.h>
#include <stdlib.h>
#include <editline/readline.h>
int try_rl_event_hook(void) {
static short hit = 0;
if (hit++ == 0) {
fprintf(stderr, "in try_rl_event_hook\n");
}
return 0;
}
int main() {
rl_event_hook = try_rl_event_hook;
while (1) {
char *input = readline("prompt> ");
if (!input) {
break;
}
printf("got input: %s\n", input);
free(input);
}
return 0;
}
If run by itself will print "in try_rl_event_hook" frequently, if run piped into grep or some other process/file will not.
>Fix:
Remove the condition checking for tty:
if (rl_event_hook) {
el_set(e, EL_GETCFN, _rl_event_read_char);
used_event_hook = 1;
}
Home |
Main Index |
Thread Index |
Old Index