Eryk Sun added the comment:

> on Windows? Will tell() and seek() reliably fail on a pipe 
> or other unseekable file?

No they will not reliably fail. 

The file position is stored in the FILE_OBJECT CurrentByteOffset. This value 
can be queried and set using the WinAPI function SetFilePointerEx, which is 
implemented via the system calls NtQueryInformationFile and 
NtSetInformationFile with the information class FilePositionInformation. 

For files opened in synchronous mode, which is the only mode that the CRT 
supports, there's a fast path in the I/O manager to bypass the I/O request 
packet (IRP) path that would normally call the device driver. This fast-path 
code trivially updates the CurrentByteOffset field, regardless of the file 
type. In synchronous mode, a seek will only fail if the file is opened without 
buffering and the new position isn't sector-aligned, as is documented for 
SetFilePointerEx and NtSetInformationFile: FilePositionInformation.

Prior to Windows 8, seek() and tell() will also fail for a console handle 
because it's not actually a kernel File handle that can be used with I/O system 
calls. OTOH, Windows 8+ uses the ConDrv device driver, so console handles 
trivially allow seek() and tell() to succeed, though the console itself ignores 
the CurrentByteOffset in the File object. Console screen-buffer files have a 
positionable cursor, which is similar but not quite the same.

A fun fact is that for files opened in asynchronous mode, for 
FilePositionInformation the I/O manager does a regular device driver  call with 
an IRP_MJ_QUERY_INFORMATION or IRP_MJ_SET_INFORMATION packet. It probably does 
this instead of using its fast path because there's no inherent meaning to the 
file position in asynchronous mode. I played around with this a bit with 
aynchronous named pipes. For setting FilePositionInformation, the NamedPipe 
filesystem driver always returns STATUS_INVALID_PARAMETER. However, querying 
the file 'position' returns the number of unread bytes in the queue for the 
handle's end of the pipe. This can only be non-zero if the handle allows 
reading, which depends on whether the pipe was created as duplex, inbound, or 
outbound. Querying this requires the NT API because SetFilePointerEx always 
calls NtSetInformationFile and fails.

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

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

Reply via email to