近日,项目涉及终端输入的问题,要不阻塞的情况下轮询串口,还要屏蔽掉 ctrl-c 等特殊键。
查了下资料,现在终端输入是有分规范和不规范两类的(canonical and noncanonical)。
- canonical : 输入以 \n EOF或者 EOL 字符串结束,就是串口想获取某键值的话,最后要敲个回车。
- nocanonical: 输入就可以获取键值。不要敲回车也可以读到。
其他的就好办了。
- 获取终端属性 tcgetattr
- 设置终端属性 tcsetattr
设置一下属性,基本都要可以找到所需要的功能了。
附上一小段code:
int get_custom_char(void)
{
struct termios org_opts, new_opts;
int c;
int ret;
/* store old settings */
ret = tcgetattr(STDIN_FILENO, &org_opts);
if (ret != 0) {
goto err;
}
memcpy(&new_opts, &org_opts, sizeof(new_opts));
new_opts.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ECHOPRT | ECHOKE | ICRNL);
/* ctrl-q */
new_opts.c_cc[VSTART] = 0;
/* ctrl-s */
new_opts.c_cc[VSTOP] = 0;
/* ctrl-z */
new_opts.c_cc[VSUSP] = 0;
/* ctrl-c */
new_opts.c_cc[VINTR] = 0;
/* set new terminal parms */
ret = tcsetattr(STDIN_FILENO, TCSANOW, &new_opts);
if (ret != 0) {
goto err;
}
c = getchar();
/* restore old settings */
ret = tcsetattr(STDIN_FILENO, TCSANOW, &org_opts);
if (ret != 0) {
goto err;
}
return c;
err:
return -1;
}