检测NUL文件描述符(isatty是假的)

下面的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 ,看它们是否匹配。