Interrupting c/c++ readline with signals

允我心安 提交于 2019-12-22 10:07:58

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!