问题
I'm attempting to interrupt readline with signals (SIGUSR1), but obviously if the signal isn't handled, the program exits, when handling, it readline proceeds as though nothing has happened. Is readline supposed to be able to be interrupted using signals.
I got the idea from this other question: force exit from readline() function
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <readline/readline.h>
#include <pthread.h>
pthread_t main_id;
void *thread_main(void* arg)
{
sleep(10);
pthread_kill(main_id, SIGUSR1);
}
void signal_handler(int sig)
{
puts("got signal");
(void) sig;
}
int main(int argc, char** argv)
{
struct sigaction sa;
sa.sa_handler = signal_handler;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaction(SIGUSR1, &sa, NULL);
main_id = pthread_self();
pthread_t id;
pthread_create(&id, NULL, thread_main, NULL);
char *input = readline("prompt> ");
puts("main thread done");
return 0;
}
The output:
$ ./test
prompt> got signal
enter something
main thread done
$
Thanks.
回答1:
Joachim Pileborg answered this question in a comment.
The best solution seems to be using the readline alternate interface. The docs are at http://www.delorie.com/gnu/docs/readline/rlman_41.html
Also an extremely basic example at http://www.mcld.co.uk/blog/blog.php?274 that just needs to be adapted to use select instead of polling with sleep.
Much better than using signals!
回答2:
Change your signal_handler
function:
void signal_handler(int sig)
{
puts("got signal");
//(void) sig;
exit(sig);
}
回答3:
libreadline
's default implementation of reading a character (int rl_getc(FILE *)
) does handle EINTR
(returned by read()
if signalled) in a way of simply re-read()
ing. Due to this receiving a signal does not cancel the readline()
.
To work around this you might set the function pointer rl_getc_function
to your own implementation to read a character (rl_getc_function
points to rl_getc()
by default).
来源:https://stackoverflow.com/questions/12290411/interrupting-c-c-readline-with-signals