On Sun, Dec 23, 2012 at 3:51 PM, Michael Goffioul <
michael.goffi...@gmail.com> wrote:

> On Sun, Dec 23, 2012 at 3:25 PM, Eli Zaretskii <e...@gnu.org> wrote:
>
>> > Date: Thu, 20 Dec 2012 19:02:03 -0500
>> > From: Michael Goffioul <michael.goffi...@gmail.com>
>> >
>> > We've got a bug report in octave [1] that seems to indicate that
>> gnulib's
>> > replacement of isatty is incorrect on Windows 8 (it's fine up to Windows
>> > 7). Looking at the implementation, it first calls the Windows _isatty
>> > version, then checks the last 2 bits of the handle associated with the
>> file
>> > descriptor, based on the assumption described in [2] (a console HANDLE
>> is
>> > not a multiple of 4). It seems that this last assumption is not valid
>> > anymore on Windows 8.
>>
>> Does the following work on Windows 8?
>>
>>   #define ISATTY(fd) (isatty(fd) && lseek(fd,SEEK_CUR,0) == -1)
>>
>> and then use ISATTY instead of isatty.
>>
>> (The lseek test is to reject other character devices, most prominently
>> the null device, with MS implementation of isatty doesn't reject.)
>>
>
> I'll ask the bug reported to try it out (I don't have Windows 8). Paolo,
> note that there's an error in your suggested code, one should test "!= 0"
> instead of equality: GetConsoleMode returns non zero on success.
>
>
Someone has finally tested the suggestions under Windows 8. Paolo's
suggestion works OK, Eli's one does not. I attached the test utility. The
results are:

test-tty.exe:

isatty (stdin): 64
IsConsoleHandle (stdin): 0
IsConsoleHandle2 (stdin): 1
ISATTY (stdin): 0
isatty (stdout): 64
IsConsoleHandle (stdout): 0
IsConsoleHandle2 (stdout): 1
ISATTY (stdout): 0

test-tty.exe <NUL:

isatty (stdin): 64
IsConsoleHandle (stdin): 0
IsConsoleHandle2 (stdin): 0
ISATTY (stdin): 0
isatty (stdout): 64
IsConsoleHandle (stdout): 0
IsConsoleHandle2 (stdout): 1
ISATTY (stdout): 0


Note, the lseek call, as suggested, is incorrect [1]. The 2nd and 3rd
argument should be swapped. However it didn't make any difference in the
test results.

Michael.

[1] http://msdn.microsoft.com/en-us/library/1yee101t(v=vs.100).aspx
#include <io.h>
#include <stdio.h>
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>

#define IsConsoleHandle(h) (((long) (h) & 3) == 3)

BOOL IsConsoleHandle2 (HANDLE h)
{
  DWORD mode;
  return GetConsoleMode (h, &mode) != 0;
}

#define ISATTY(fd) (isatty(fd) && lseek(fd,SEEK_CUR,0) == -1)

int main (int argc, char **argv)
{
  printf ("isatty (stdin): %d\n", isatty (fileno (stdin)));
  printf ("IsConsoleHandle (stdin): %d\n",
          IsConsoleHandle ((HANDLE) _get_osfhandle (fileno (stdin))));
  printf ("IsConsoleHandle2 (stdin): %d\n",
          IsConsoleHandle2 ((HANDLE) _get_osfhandle (fileno (stdin))));
  printf ("ISATTY (stdin): %d\n", ISATTY (fileno (stdin)));

  printf ("isatty (stdout): %d\n", isatty (fileno (stdout)));
  printf ("IsConsoleHandle (stdout): %d\n",
          IsConsoleHandle ((HANDLE) _get_osfhandle (fileno (stdout))));
  printf ("IsConsoleHandle2 (stdout): %d\n",
          IsConsoleHandle2 ((HANDLE) _get_osfhandle (fileno (stdout))));
  printf ("ISATTY (stdout): %d\n", ISATTY (fileno (stdout)));

  return 0;
}

Reply via email to