Readline的:获取SIGINT一个新的提示 [英] Readline: Get a new prompt on SIGINT

查看:194
本文介绍了Readline的:获取SIGINT一个新的提示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有类似如下code,使用readline的:

I've got code similar to the following, using readline:

#include <errno.h>
#include <error.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <readline/readline.h>
#include <readline/history.h>

void handle_signals(int signo) {
  if (signo == SIGINT) {
    printf("You pressed Ctrl+C\n");
  }
}

int main (int argc, char **argv)
{
   //printf("path is: %s\n", path_string);
  char * input;
  char * shell_prompt = "i-shell> ";
  if (signal(SIGINT, handle_signals) == SIG_ERR) {
    printf("failed to register interrupts with kernel\n");
  }

  //set up custom completer and associated data strucutres
  setup_readline();

  while (1) 
  {
    input = readline(shell_prompt);
    if (!input)
      break;
    add_history(input);

    //do something with the code
    execute_command(input);

  }  
  return 0;
}

我知道了设置拦截 SIGINT (即用户pressing 按Ctrl + C ) ,所以我可以告诉大家,信号处理程序 handle_signals()正在工作。然而,当控制返回到的ReadLine(),它使用文本的同一行,它是使用之前的输入。我想发生是readline的为取消文本的当前行,并给我一个新的生产线,就像在bash shell。像这样:

I've got it set up to intercept SIGINT (i.e. user pressing Ctrl+C), so I can tell that the signal handler handle_signals() is working. However, when control returns to readline(), it's using the same line of text it was using prior to the input. What I'd like to happen is for readline to "cancel" the current line of text and give me a new line, much like the BASH shell. Something like so:

i-shell> bad_command^C
i-shell> _

得到这个工作机会吗?我用读提及的邮件列表上的东西的longjmp(2),但确实似乎不是一个好主意。

Any chance of getting this to work? Something on a mailing list I read mentioned using longjmp(2), but that really doesn't seem like a good idea.

推荐答案

您在你想使用的的longjmp线正确的。但由于longjmp的是在信号处理程序,您需要使用此时sigsetjmp / siglongjmp。

You are correct in your line of thinking to use longjmp. But because the longjmp would be in a signal handler, you need to use sigsetjmp/siglongjmp.

由于使用code作为基本一个简单的例子:

As a quick example using your code as a base:

#include <setjmp.h>
#include <errno.h>
#include <error.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <readline/readline.h>
#include <readline/history.h>

sigjmp_buf ctrlc_buf;

void handle_signals(int signo) {
  if (signo == SIGINT) {
    printf("You pressed Ctrl+C\n");
    siglongjmp(ctrlc_buf, 1);
  }
}

int main (int argc, char **argv)
{
   //printf("path is: %s\n", path_string);
  char * input;
  char * shell_prompt = "i-shell> ";
  if (signal(SIGINT, handle_signals) == SIG_ERR) {
    printf("failed to register interrupts with kernel\n");
  }

  //set up custom completer and associated data strucutres
  setup_readline();

  while ( sigsetjmp( ctrlc_buf, 1 ) != 0 );

  while (1) 
  {
    input = readline(shell_prompt);
    if (!input)
      break;
    add_history(input);

    //do something with the code
    execute_command(input);

  }  
  return 0;
}

siglongjmp返回0以外的值(在这种情况下,1)此时sigsetjmp所以while循环调用此时sigsetjmp试(成功返回此时sigsetjmp的值为0),然后将readline的再次调用。

siglongjmp returns a value other than 0 (in this case a 1) to sigsetjmp so the while loop calls sigsetjmp again (a successful return value of sigsetjmp is 0) and will then call readline again.

这也可能是有用的设置 rl_catch_signals = 1 ,然后调用 rl_set_signals()这样的ReadLine信号处理信号传递给你的程序,你会再跳回调用readline的第二次之前清理它需要的任何变量。

it may also be helpful to set rl_catch_signals = 1 and then call rl_set_signals() so that the readline signal handling cleans up any variables it needs to before passing the signal to your program where you will then jump back to call readline a second time.

这篇关于Readline的:获取SIGINT一个新的提示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆