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

Edw*_*ang 7 c windows terminal

当NUL通过管道输出时,以下C文件给出了伪造的结果:

int main()
{
  printf("_isatty = %d\n", _isatty(0));
}
Run Code Online (Sandbox Code Playgroud)

结果是:

C:\Users\Edward\Dev\nulltest> test.exe < NUL
_isatty = 64
Run Code Online (Sandbox Code Playgroud)

我很确定NUL(又名/ dev/null)不是终端设备!所以我需要以另一种方式检测文件描述符是否对应于NUL.这个数字没有任何具体含义; 当我确实连接了一个终端时,我看到了它.

我该怎么办?这个问题建议使用粗略的未记录的函数来获取基础名称,可能是将它与NUL进行比较,但这对我来说感觉不太理想.有没有更好的办法?

PS这将有助于解决这个GHC错误.

iks*_*aif 4

来自msdn

如果描述符与字符设备关联,则 _isatty 返回非零值。否则,_isatty 返回 0。

NUL 就像 Unix 上的 /dev/null 一样,它是一个字符设备。

请注意,在 Linux 上,isatty 有所不同:

isatty() 函数测试 fd 是否是引用终端的打开文件描述符。

您可以做的是尝试将 STDIN_FILENO (0) 与 ${cwd}/NUL 进行比较(使用 stat 或 stat)。

更新:

int ret = GetFileType(GetStdHandle(STD_INPUT_HANDLE));
Run Code Online (Sandbox Code Playgroud)

对于 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");
Run Code Online (Sandbox Code Playgroud)