代码之家  ›  专栏  ›  技术社区  ›  Edward Z. Yang

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

  •  7
  • Edward Z. Yang  · 技术社区  · 14 年前

    int main()
    {
      printf("_isatty = %d\n", _isatty(0));
    }
    

    结果是:

    C:\Users\Edward\Dev\nulltest> test.exe < NUL
    _isatty = 64
    

    我很确定NUL(aka/dev/null)不是终端设备!所以我需要用另一种方法来检测文件描述符是否对应于NUL。这个数字没有任何特定的含义;我看到它的时候,我真的有一个终端连接。

    我该怎么办? This question 建议使用一个粗略的、没有文档的函数来获取基础名称,可能是将其与NUL进行比较,但我觉得这不太理想。有更好的办法吗?

    另外,这将有助于解决 this GHC bug .

    3 回复  |  直到 8 年前
        1
  •  4
  •   iksaif    14 年前

    msdn :

    字符设备。否则,我就死定了 返回0。

    请注意,在Linux上,isatty是不同的:

    函数的作用是:测试fd 是一个打开的文件描述符 到终点站。

    您可以尝试比较STDIN\u FILENO(0)和${cwd}/NUL(使用stat或stat)。

    int ret = GetFileType(GetStdHandle(STD_INPUT_HANDLE));
    

    它将返回NUL或tty的文件类型字符。

    看到了吗 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");
    
        2
  •  0
  •   Edward Z. Yang    14 年前

    这里有一个可能的解决方案,但我不相信它一直都有效。我相信它适用于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;
    }
    
        3
  •  -2
  •   R.. GitHub STOP HELPING ICE    14 年前

    fstat 并比较结果的设备成员 stat 与之相适应的结构 /dev/null 看看他们是否匹配。