bash 输入重定向破坏了标准输入
我有一个看起来像这样的程序:
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <errno.h>
int enable_keyboard() {
struct termios new_term_attr;
tcgetattr(fileno(stdin), &new_term_attr);
new_term_attr.c_lflag &= ~(ECHO|ICANON);
new_term_attr.c_cc[VTIME] = 0;
new_term_attr.c_cc[VMIN] = 0;
return tcsetattr(fileno(stdin), TCSANOW, &new_term_attr);
}
int main() {
errno = 0;
unsigned char field[H][W];
fill (field);
char c = enable_keyboard();;
while(1) {
read(0, &c, 1);
printf("%d ", c);
}
}
它从标准输入读取单个字符并无限显示它(以检查enable_keybord是否正常工作)。
问题是,当我使用输入重定向(行 ./a.out
errno
设置为25.
另外,tcsetattr
在应该返回 0 或 -1 时却返回 -201。
我尝试在 tcsetattr
之前使用 scanf
清除 stdin
并完全禁用 tcsetattr
但事实证明输入重定向全部挂起输入完全。
如果没有输入重定向,一切都工作得很好,所以我想也许 bash 用 stdin 做了一些事情,所以它在程序中冻结了。
有什么想法如何解决这个问题吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
errno
25 = "设备的 ioctl 不合适";您正在对文件执行终端操作。您不检查 tcgetattr() 的返回结果。出错时,它会设置errno
,如果文件描述符不代表终端,则设置为ENOTTY
。所以:这并不能解决你的“挂起”问题 - 正如你所提到的,你的程序无限循环 - while 循环不会在 EOF 上终止。问题是 EOF 没有由 read() 明确指示 - 相反它返回零 - 这对于终端输入来说仅仅意味着没有字符。在这种情况下:
将所有这些放在一起:
errno
25 = "Inappropriate ioctl for device"; you are performing terminal operations on a file. You do not check the return fromtcgetattr()
. On error, it setserrno
and that is set toENOTTY
if the file descriptor does not represent a terminal. So:That will not solve your "hanging" issue however - as you mentioned, your program loops indefinitely - the while loop does not terminate on EOF. The problem is that EOF is not explicitly indicated by
read()
- rather it returns zero - which for terminal input simply mean no characters. In that case:Putting that all together: