On Fri, Oct 6, 2017 at 1:31 PM, Thomas Jollans <t...@tjol.eu> wrote:
> On 2017-10-06 12:33, Ben Bacarisse wrote:
>
>> A general solution to the (rather odd) complaint about silent waiting
>> should really check any input fileno to see if a prompt is needed.  You
>> could argue, though, that anyone who's re-arranged a program's input so
>> that some non-zero input fileno is attached to a terminal won't need the
>> prompt!
>
> stdin is ALWAYS fileno 0, whether the input is attached to a tty or not.
> The only situation where sys.stdin.fileno() != 0 is when sys.stdin has
> been reassigned from within python.
>
> $ python -c 'import sys; print(sys.stdin.fileno())' < /dev/zero
> 0
>
> This should be true for all platforms, or at least all platforms python
> supports.

POSIX defines STDIN_FILENO as 0, and the Windows C runtime reserves FD
0 to map to the native StandardInput handle. But as I noted in a
previous message, on Windows isatty(0) returns true if a process isn't
executed with a valid StandardInput. In this case sys.stdin will be
None, so call sys.stdin.fileno() and handle the exception if that
fails.

If you really need to know that stdin is interactive for something
critical, then isatty() is the wrong function on Windows. You need to
check for a console, which is most easily done by using ctypes to call
GetConsoleMode. For example:

    import os

    if os.name == 'posix':
        from os import isatty

    elif os.name == 'nt':
        import ctypes
        import msvcrt
        kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)

        def isatty(fd):
            """Return True if the fd is connected to a console."""
            try:
                handle = ctypes.c_void_p(msvcrt.get_osfhandle(fd))
            except (OSError, IOError):
                return False
            mode = ctypes.c_ulong()
            success = kernel32.GetConsoleMode(handle, ctypes.byref(mode))
            return bool(success)
-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to