Eryk Sun <eryk...@gmail.com> added the comment:

In Windows, the C runtime's append mode doesn't use the native file append 
mode. The CRT just opens the file in read-write mode and seeks to the end, 
initially and before each write. 

subprocess.Popen() doesn't implement inheritance of file descriptors, so the 
CRT append mode gets lost, but the native file pointer is of course retained. 
After file.write_text('') in the parent overwrites the file, writes to stdout 
in the child process begin at the file pointer. Null values are written to the 
initial 11 bytes.

You could use os.spawnv() to inherit file descriptors. The C runtime uses 
reserved fields in the process STARTUPINFO in order to marshal the fd data to 
the child process. This depends on the child implementing a compatible scheme 
for C file descriptors, which of course is the case for applications that use 
MSVC. A downside is that this won't be thread-safe since you'll have to 
temporarily redirect stdout in the current process. For example:

    old_stdout = os.dup(1)
    with file.open(mode='a') as f:
        os.dup2(f.fileno(), 1)
    try:
        os.spawnv(os.P_NOWAIT, sys.executable, ['python', 'sub.py'])
    finally:
        os.dup2(old_stdout, 1)

Alternatively, you could open the file with native append mode and wrap the OS 
handle in a file descriptor. For example:

    import os
    import msvcrt
    from win32file import *
    from ntsecuritycon import FILE_APPEND_DATA

    h = CreateFile(os.fspath(file), FILE_APPEND_DATA, 
            FILE_SHARE_READ | FILE_SHARE_WRITE, None, OPEN_EXISTING, 0, None)
    fd = msvcrt.open_osfhandle(h.Detach(), 0)

    with open(fd) as f:
        popen = subprocess.Popen([sys.executable, 'sub.py'], stdout=f)

----------
components: +Windows
nosy: +eryksun, paul.moore, steve.dower, tim.golden, zach.ware
versions: +Python 3.10, Python 3.11, Python 3.9 -Python 3.8

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

Reply via email to