NUL file descriptor detection (isatty is dummy)

The following C file gives a dummy result when a NUL is sent to it:

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

result:

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

I am sure that NUL (aka / dev / null) is not a terminal device! Therefore, I need to determine in a different way whether the file descriptor matches the NUL. The number has no particular meaning; I see this when I really have a terminal.

What should I do? This question suggests using a sketchy undocumented function to get the main name, presumably comparing it to NUL, but to me it seems less than ideal. Is there a better way?

PS This will help solve this GHC error .

+7
c windows terminal
source share
3 answers

From msdn :

_isatty returns a nonzero value if the descriptor is associated with a character device. Otherwise, _isatty returns 0.

NUL is like / dev / null on Unix, it's a char device.

Note that on Linux isatty is different:

The isatty () function checks if fd is an open file descriptor that refers to a terminal.

What you can do is try to compare STDIN_FILENO (0) with $ {cwd} / NUL (using stat or stat).

Update:

 int ret = GetFileType(GetStdHandle(STD_INPUT_HANDLE)); 

It will return FILE_TYPE_CHAR for NUL or tty.

See the GetFileType documentation for other values. You can detect files / char device / pipes.

Update Final:

Use GetConsoleMode for input and GetConsoleScreenBufferInfo for output.

 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"); 
+4
source share

Here is a possible solution, but I'm not sure if it works all the time. I believe that it will work for a specific case of a NUL file descriptor:

 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 not a TTY.  * /
         return 0;
     }
     return 1;
 }
0
source share

You can use fstat in the file descriptor and compare the device element of the resulting stat structure with that for /dev/null and see if they match.

-2
source share

All Articles