if STREAM.isatty():

Terry Reedy tjreedy at udel.edu
Fri Aug 30 13:34:04 EDT 2019


Eric, thank you for the detailed answer.  I stashed it away for future 
review ;-).

On 8/30/2019 3:10 AM, Eryk Sun wrote:
> On 8/29/19, Terry Reedy <tjreedy at udel.edu> wrote:
>> On 8/29/2019 10:16 AM, Eryk Sun wrote:
>>
>>> In Windows, isatty() is true for any character-type file.
>>
>> Does that mean one that can either send or receive data a character at a
>> time, as opposed to a block at a time?
> 
> Yes, any number of bytes can be written to a character device, whereas
> a block device will require some fixed number of bytes such as a
> 512-byte disk sector.
> 
> WINAPI GetFileType classifies files for all of the following NT device
> types as FILE_TYPE_CHAR (akin to Unix S_IFCHR):
> 
>      FILE_DEVICE_CONSOLE
>      FILE_DEVICE_NULL
>      FILE_DEVICE_SERIAL_PORT
>      FILE_DEVICE_PARALLEL_PORT
>      FILE_DEVICE_KEYBOARD
>      FILE_DEVICE_MOUSE
>      FILE_DEVICE_MODEM
>      FILE_DEVICE_PRINTER
>      FILE_DEVICE_SCREEN
>      FILE_DEVICE_SOUND
> 
> FILE_DEVICE_CONSOLE is for the ConDrv console device, which was added
> in Windows 8. In previous versions, GetFileType special cases console
> pseudohandles.
> 
> GetFileType classifies files for all of the following NT device types
> as FILE_TYPE_DISK (akin to Unix S_IFBLK):
> 
>      FILE_DEVICE_DISK
>      FILE_DEVICE_VIRTUAL_DISK
>      FILE_DEVICE_CD_ROM
>      FILE_DEVICE_DISK_FILE_SYSTEM
>      FILE_DEVICE_CD_ROM_FILE_SYSTEM
>      FILE_DEVICE_DFS
>      FILE_DEVICE_DATALINK
>      FILE_DEVICE_CONTROLLER
> 
>> Aha.  So this is why
>> https://pubs.opengroup.org/onlinepubs/009695399/functions/isatty.html
>> follows the doc for isatty, which says 'associated with a terminal
>> device', with an information section that contradicts that with
>> "The isatty() function does not necessarily indicate that a human being
>> is available for interaction via fildes. It is quite possible that
>> non-terminal devices are connected to the communications line."
> 
> As far as I know, only the Windows CRT classifies any character device
> as a TTY. Linux doesn't. "/dev/null" is a character device, but not a
> TTY.
> 
> I think the CRT's _isatty implementation is wrong, though I'm not
> certain what the right answer looks like. Windows doesn't have any
> notion of a tty/pty terminal. I suppose it can just check for a
> console. For older versions of Windows that would be based on checking
> for a console pseudohandle. In Windows 8+, we can query
> NtQueryVolumeInformationFile: FileFsDeviceInformation to check for
> FILE_DEVICE_CONSOLE. (It would be useful if they exposed this in the
> Windows API, maybe as GetVolumeInformationByHandleEx, like what they
> did for GetFileInformationByHandleEx.)
> 
>> What makes a pipe on Windows not a character file?  Is data sent between
>> processes a block at a time?  Are posix pipes different?
> 
> FILE_TYPE_PIPE (akin to Unix S_IFIFO) is a type that accesses a
> section of shared memory that's used as an inter-process communication
> channel. Requesting a read on an empty pipe blocks until at least one
> byte is available. Requesting a write on a pipe blocks until there's
> available space for the write to complete, which may require multiple
> reads at the other end. (Note that Windows also classifies sockets as
> 'pipes', but Unix has a dedicated S_IFSOCK type for sockets.)
> 
> A pipe channel can be inbound (client-write, server-read), outbound
> (server-write, client-read), or duplex (read-write on both ends).
> Anonymous pipes are in duplex mode but they're opened with access on
> each end that makes them effectively inbound mode. Windows also
> supports message-mode pipes, which handles each write as a message. A
> message-mode pipe can be configured to be read in either byte mode or
> message mode. (Pipes in most Unix systems do not support duplex and
> message modes.)
> 
> In principle, a pipe can be used as the IPC channel for an interactive
> terminal. For example, MSYS2 does this with specially named pipes that
> its isatty() function special cases as a TTYs. But in general we
> expect pipes to be non-interactive, and for performance we default to
> full buffering with pipes instead of line buffering. Full buffering is
> incompatible with interactive usage.
> 
>> I don't understand the following.
>> ---
>> C:\Users\Terry>python -c "print('hello\n') | python
>> hello
>>
>> Traceback (most recent call last):
>>     File "<string>", line 1, in <module>
>> NameError: name 'python' is not defined
> 
> The command line is missing the closing double quote around
> "print('hello\n')". In this case, CMD acts as if the whole statement
> is quoted, so the vertical bar is not interpreted as a pipe to a
> `python` command. Let's print the command line for the python.exe
> process in order to demonstrate this:
> 
>      C:\>python -c "import win32api;print(win32api.GetCommandLine()) | python
>      python  -c "import win32api;print(win32api.GetCommandLine()) | python
>      Traceback (most recent call last):
>        File "<string>", line 1, in <module>
>      NameError: name 'python' is not defined
> 


-- 
Terry Jan Reedy




More information about the Python-list mailing list