我试图允许一个中断导致某个值由readline返回。下面是一个很小的例子:
#include <stdio.h>
#include <signal.h>
#include <readline/readline.h>
void handler (int status)
{
rl_replace_line("word",0);
rl_redisplay();
rl_done = 1;
}
int main (int argc, char** argv)
{
char* entry;
signal(SIGINT,handler);
entry = readline("");
printf("\nEntry was: %s\n", entry);
return 0;
}如果我运行这段代码并按下Control,在我点击ENTER之后,它一定会打印"Entry it : word“。但我希望它这样做,而不需要用户按回车。我基本上只是想在收到中断信号时将条目设置为"word“,结束读行功能。我一直无法找到任何关于如何结束readline循环并返回某个值的文档(我肯定它就在那里,但我没有找到它)。
我试过的一件事就是添加
(*rl_named_function("accept-line"))(1,0);在处理程序的末尾,但它没有立即将文本发送到"entry“。
发布于 2018-11-06 07:33:59
我不相信您可以从异步信号处理程序调用回readline函数。(它“似乎”起作用这一事实并不能保证它不会不时灾难性地失败。)通常,您应该在信号处理程序中执行绝对最小值,例如设置标志以指示信号已经接收。
读行库提供变量rl_signal_event_hook,其值是当读行调用被信号中断时将被调用的函数。将任何修改readline状态的代码放入这样的函数中可能是明智的。
但是,这里似乎最安全的解决方案是安排将Control字符直接传递到读行,而不触发SIGINT。您可以根据由termios返回的tcgetattr结构创建一个自定义终端设置,该结构关闭Ctrl到INTR函数的映射,方法是取消ISIG标志(这也将关闭其他中断字符,包括Ctrl),或者将c_cc[VINTR]更改为_POSIX_VDISABLE (或其他键)。
如果您在Windows上而不是使用Cygwin,这包括termios仿真,您可以使用本地API来启用和禁用Control处理。
然后可以使用rl_bind_key将Ctrl(即3)绑定到您自己的函数。该函数需要匹配rl_command_func_t typedef,即int(*)(int, int)。函数应该返回0;在简单的情况下,您可能可以忽略参数,但对于记录,第一个参数是"count“(通过按住Alt键输入一个数字而输入的数值参数),而第二个参数是键本身。
您可能应该在修改termios结构之前复制它,这样您就可以在完成之后重置终端设置。通常,您希望在每次调用readline时安装和恢复终端设置(这也是readline本身所做的)。
发布于 2018-11-06 07:32:50
我想我有你想要的东西。
#include <stdio.h>
#include <signal.h>
#include <readline/readline.h>
int event(void) { }
void handler (int status)
{
rl_replace_line("word",0);
rl_redisplay();
rl_done = 1;
}
int main (int argc, char** argv)
{
char* entry;
rl_event_hook=event;
signal(SIGINT,handler);
entry = readline("");
printf("\nEntry was: %s\n", entry);
return 0;
}秘诀是,rl_done只在事件循环中签入。当您给它一个空事件钩子函数时,它会检查rl_done并退出。
发布于 2018-11-06 04:59:38
CTRL+C应该向您的程序传递一个SIGINT或类似的中断信号。应该有一些方法来覆盖处理,例如,请参阅这里。
https://stackoverflow.com/questions/53165704
复制相似问题