我目前正在开发一个用C语言构建的完整shell。
我想在我的双链表中使用箭头键实现bash历史和导航,但我遇到了一些TermCaps和正确的麻烦
设置read()
功能。
以下是我设置终端的方法:
static int set_terminal_mode(t_shell *shell, const int mode)
{
char *term_name;
if (mode == 0)
{
if ((term_name = getenv("TERM")) == NULL)
return (-1);
ioctl(0, TCGETS, &shell->term);
shell->term.c_lflag &= ~ICANON;
shell->term.c_cc[VMIN] = 1;
shell->term.c_cc[VTIME] = 0;
ioctl(0, TCGETS, &shell->term_save);
ioctl(0, TCSETS, &shell->term);
}
if (mode == 1)
ioctl(0, TCSETS, &shell->term_save);
return (0);
}
我可以在按下左键或右键时捕捉到然后我使用\r
来删除该行(它不能正常工作),但主要问题是我不能再使用返回键了(仅显示^?
)
我该如何解决这个问题?
答案 0 :(得分:0)
这一行
shell->term.c_lflag &= ~ICANON;
关闭规范模式,according to POSIX执行多项操作,包括关闭行缓冲,其中包括回车的特殊处理:
在非规范模式输入处理中,输入字节不会组合成行,不会发生擦除和终止处理。
和
<强>
CR
强>
输入上的特殊字符,如果设置了ICANON
标记,则会识别该字符;它是回车符。如果设置了ICANON
和ICRNL
并且未设置IGNCR
,则应翻译此字符进入NL
,并且与NL
字符具有相同的效果。
如果要读取单个字节(对于光标键),则必须处理单字节控制字符,例如回车符(CR
)和换行符(称为{{1或者换行符。
顺便说一句,您的示例似乎已将已保存/已修改的设置反转:调用
NL
使用
中保存的终端设置 ioctl(0, TCSETS, &shell->term_save);
在您修改了终端设置之后。