Eryk Sun added the comment:

Martin, the console should be in line-input mode, in which case ReadConsole 
will block if there isn't at least one line in the input buffer. It reads up to 
the lesser of a complete line or the number of UTF-16 codes requested. If the 
previous call read the entire request size but didn't stop on '\n', then we 
know the next call shouldn't block because the input buffer has at least one 
'\n' in it.

> I can validate that we can open the console IO object from 
> 0, 1, 2, "CON", "CONIN$" and "CONOUT$", get fileno(), check
> readable()/writable() and close (multiple times without 
> crashing).

I like the idea to have fileno() lazily get a file descriptor on demand, but 
_open_osfhandle is a low I/O function that uses _open flags -- not 'rb' (int 
0x7262) or 'wb' (int 0x7762). ;-)

You can use _O_RDONLY | _O_BINARY or _O_WRONLY | _O_BINARY. But really those 
values would be ignored anyway. It's not actually opening the file, so it only 
cares about a few flags. Specifically, in lowio\osfinfo.cpp I see that it looks 
for _O_APPEND, _O_TEXT, and _O_NOINHERIT. 

On line 329, the following assignment

        if (self->writable)
            access |= GENERIC_WRITE;

should be `access = GENERIC_WRITE`. Requesting both read and write access is an 
invalid parameter when opening "CON", as can be seen here:

    >>> f = open('CON', 'wb', buffering=0)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    OSError: [WinError 87] The parameter is incorrect: 'CON'

CONOUT$ works, of course:

    >>> f = open('CONOUT$', 'wb', buffering=0)
    >>> f
    <_io._WindowsConsoleIO mode='wb' closefd=True>

Lastly, for a readall that starts with ^Z, you're still breaking out of the 
loop before incrementing len, which is thus 0 when subsequently checked. It 
ends up calling WideCharToMultiByte with len == 0, which fails.

    >>> sys.stdin.buffer.raw.read()
    ^Z
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    OSError: [WinError 87] The parameter is incorrect

> I can't actually come up with many useful tests for this... 

ctypes can be used to write to the input buffer and read from a screen buffer. 
For the latter it helps to first create and activate a scratch screen buffer, 
initialized to NULs to make it easy to read back everything that was written up 
to the current cursor position. I have existing ctypes code for this, written 
to solve the problem of a subprocess that stubbornly writes directly to the 
console instead of writing to stdout/stderr pipes.

----------
nosy: +eryksun

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue1602>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to