下面的C文件在NUL被传送给它时给出了一个伪造的结果:
int main() { printf("_isatty = %d\n", _isatty(0)); }
结果是:
C:\Users\Edward\Dev\nulltest> test.exe < NUL _isatty = 64
我很确定NUL(aka / dev / null)不是terminal设备! 所以我需要以另一种方式检测文件描述符是否对应于NUL。 这个数字没有任何具体的含义; 当我确实有一个terminal连接时,我看到它。
我该怎么办? 这个问题build议使用一个粗略的未logging的函数来获取底层名称,大概是将它与NUL进行比较,但这对我来说并不理想。 有没有更好的办法?
PS这将有助于解决这个GHC错误 。
从msdn :
如果描述符与字符设备关联,则_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));
它将返回NLE或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");
这是一个可能的解决方案,但我不相信它一直工作。 我相信这将适用于NUL文件描述符的特定情况:
int real_isatty(int fd){ DWORD st; HANDLE h; if(!_isatty(fd)){ / * TTY必须是字符设备* / 返回0; } h =(HANDLE)_get_osfhandle(fd); if(h == INVALID_HANDLE_VALUE){ / *破碎的手柄不能成为终端* / 返回0; } if(!GetConsoleMode(h,&st)){ / * GetConsoleMode在不是TTY时似乎失败。 * / 返回0; } 返回1; }
您可以在fstat
上使用fstat
,并将生成的stat
结构的设备成员与/dev/null
,看它们是否匹配。