Mam*_*pac 3 c terminal signals
再会,
我正在为我的学校用 C 语言编写自己的 shell,它必须bash尽可能相似。
我必须像bash以前那样处理 Ctrl-\ 和 Ctrl-C 等信号;因此我可以使用signal函数。它工作正常,但问题是每当捕获 Ctrl-C 信号时(从第二个捕获开始),^C就会打印 a 。
在网上,我发现了一种解决方法,建议"\b \b\b \b\nminishell$ "在捕获 Ctrl-C 时进行打印,这将吞噬这两个符号。问题是,由于第一次^C没有打印,打印吞噬了我提示的两个符号,使其变成minishell了minishell$ ,光标显示不正确。
现在我为这个解决方法提出了另一个解决方法,即声明一个静态布尔值,以便在第一次调用时不打印 baskspaces。但这在 Ctrl-\ 的情况下没有帮助;当我尝试写入必须替换 的两个空格时,Ctrl-\ 继续将光标向右移动^\。
我不喜欢这些解决方法,想知道是否有办法指示终端不输出这些东西?我可以使用tgetent, tgetflag, tgetnum, tgetstr, tgoto, tputs, tcsetattr, tcgetattr, 已阅读他们的手册页,但似乎没有任何帮助。
当您在终端上键入按键时,会发生两件事
这两个操作都可以通过 termios/tcsetattr() 进行控制:可以发送或回显不同的字符,可以抑制某些字符等(这些操作中的一些/大部分发生在终端驱动程序中,但这是此处不相关)
演示:用于tcsetattr()控制终端的回显:
#include <stdio.h>
#include <stdlib.h>
#define _SVID_SOURCE 1
#include <termios.h>
#include <unistd.h>
#include <signal.h>
struct termios termios_save;
void reset_the_terminal(void)
{
tcsetattr(0, 0, &termios_save );
}
sig_atomic_t the_flag = 0;
void handle_the_stuff(int num)
{
char buff[4];
buff[0] = '[';
buff[2] = '0' + num%10;
num /= 10;
buff[1] = '0' + num%10;
buff[3] = ']';
write(0, buff, sizeof buff);
the_flag = 1;
}
int main (void)
{
int rc;
int ch;
struct termios termios_new;
rc = tcgetattr(0, &termios_save );
if (rc) {perror("tcgetattr"); exit(1); }
rc = atexit(reset_the_terminal);
if (rc) {perror("atexit"); exit(1); }
termios_new = termios_save;
termios_new.c_lflag &= ~ECHOCTL;
rc = tcsetattr(0, 0, &termios_new );
if (rc) {perror("tcsetattr"); exit(1); }
signal(SIGINT, handle_the_stuff);
printf("(pseudoshell)Start typing:\n" );
while(1) {
ch = getc(stdin);
if (the_flag) {
printf("Saw the signal, last character was %02x\n", (unsigned) ch);
break;
}
}
exit (0);
}
Run Code Online (Sandbox Code Playgroud)