0

我目前正在开发一个用 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来擦除线(这实际上不起作用)但主要问题是我不能再使用返回键(仅显示^?)我该如何解决这个问题?

4

1 回答 1

0

这条线

       shell->term.c_lflag &= ~ICANON;

关闭规范模式,根据 POSIX ,它会做几件事,包括关闭行缓冲,其中包括对回车的特殊处理:

在非规范模式输入处理中,输入字节不组装成行,不会发生擦除和终止处理。

CR
输入时的特殊字符,如果ICANON设置了标志,则可以识别;它是回车符。当ICANONandICRNL被设置和IGNCR不被设置时,这个字符应该被翻译成一个NL, 并且应该和一个字符具有相同的效果NL

如果要读取单字节(用于光标键),则必须处理单字节控制字符,例如回车符 ( CR) 和换行符(称为NL或换行符)。

顺便说一句,您的示例似乎将保存/修改的设置颠倒了:调用

     ioctl(0, TCSETS, &shell->term_save);

使用保存在

       ioctl(0, TCGETS, &shell->term_save);

这是在您已经修改了终端设置之后。

于 2016-06-08T01:04:55.260 回答