当NUL通过管道输出时,以下C文件会出现虚假结果:
int main()
{
printf("_isatty = %d\n", _isatty(0));
}
结果是:
C:\Users\Edward\Dev\nulltest> test.exe < NUL
_isatty = 64
我很确定NUL(又名/ dev / null)不是终端设备!所以我需要以另一种方式检测文件描述符是否对应于NUL。这个数字没有任何具体含义;当我确实连接了一个终端时,我就看到了它。
我该怎么办? This question建议使用粗略的未记录的函数来获取基础名称,可能是将它与NUL进行比较,但这对我来说感觉不太理想。还有更好的方法吗?
P.S。这有助于解决this GHC bug。
答案 0 :(得分:4)
来自msdn:
如果描述符与a关联,则_isatty返回非零值 角色设备。否则,_isatty 返回0。
NUL就像Unix上的/ dev / null,它是一个char设备。
请注意,在Linux上,isatty是不同的:
isatty()函数测试是否为fd 是一个打开的文件描述符引用 到终点站。
你可以做的是尝试将STDIN_FILENO(0)与$ {cwd} / NUL(使用stat或stat)进行比较。
<强>更新强>
int ret = GetFileType(GetStdHandle(STD_INPUT_HANDLE));
它将为NUL或tty返回FILE_TYPE_CHAR。
有关其他值,请参阅GetFileType文档。您可以检测文件/字符设备/管道。
更新最终结果:
使用GetConsoleMode输入,GetConsoleScreenBufferInfo输出。
CONSOLE_SCREEN_BUFFER_INFO sbi;
DWORD mode;
if (!GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode))
fprintf(stderr, "not console\n");
else
fprintf(stderr, "console\n");
if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &sbi))
fprintf(stderr, "not console\n");
else
fprintf(stderr, "console\n");
答案 1 :(得分:0)
这是一个可能的解决方案,但我不相信它一直有效。我相信它适用于NUL文件描述符的特定情况:
int real_isatty(int fd) { DWORD st; HANDLE h; if (!_isatty(fd)) { /* TTY must be a character device */ return 0; } h = (HANDLE)_get_osfhandle(fd); if (h == INVALID_HANDLE_VALUE) { /* Broken handle can't be terminal */ return 0; } if (!GetConsoleMode(h, &st)) { /* GetConsoleMode appears to fail when it's not a TTY. */ return 0; } return 1; }
答案 2 :(得分:-2)
您可以在文件描述符上使用fstat
,并将生成的stat
结构的设备成员与/dev/null
结构进行比较,看看它们是否匹配。