gpt4 book ai didi

c - Readline:在 SIGINT 上获取新提示

转载 作者:太空狗 更新时间:2023-10-29 16:40:48 27 4
gpt4 key购买 nike

我有类似下面的代码,使用 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(即用户按下 Ctrl+C),因此我可以判断信号处理程序 handle_signals() 正在工作。但是,当控制返回到 readline() 时,它使用的是与输入之前相同的文本行。我希望 readline 能够“取消”当前文本行并给我一个新行,就像 BASH shell 一样。像这样:

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

有没有机会让它发挥作用?我读到的邮件列表中提到了使用 longjmp(2) 的内容,但这看起来确实不是个好主意。

最佳答案

您使用 longjmp 的思路是正确的。但是因为 longjmp 将在信号处理程序中,所以您需要使用 sigsetjmp/siglongjmp。

作为使用您的代码作为基础的快速示例:

#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 my_cmd_loop(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)
{
while ( sigsetjmp( ctrlc_buf, 1 ) != 0 );

input = readline(shell_prompt);
if (!input)
break;
add_history(input);

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

}
return 0;
}

siglongjmp 向 sigsetjmp 返回一个非 0 的值(在本例中为 1),因此 while 循环再次调用 sigsetjmp(sigsetjmp 的成功返回值为 0),然后将再次调用 readline。

设置 rl_catch_signals = 1 然后调用 rl_set_signals() 也可能会有帮助,这样 readline 信号处理会在传递信号之前清除它需要的任何变量到您的程序,然后您将跳回以第二次调用 readline。

关于c - Readline:在 SIGINT 上获取新提示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16828378/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com