subprocess.Popen inheriting

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Thu Dec 18 19:11:15 EST 2008


En Thu, 18 Dec 2008 08:35:58 -0200, Aaron Brady <castironpi at gmail.com>
escribió:

> On Dec 17, 7:16 pm, "Gabriel Genellina" <gagsl-... at yahoo.com.ar>
> wrote:
>> En Wed, 17 Dec 2008 22:46:32 -0200, Aaron Brady <castiro... at gmail.com>  
>> escribió:
>>
>>
>>
>> > On Dec 17, 5:05 pm, "Gabriel Genellina" <gagsl-... at yahoo.com.ar>
>> > wrote:
>> >> En Wed, 17 Dec 2008 12:21:38 -0200, Jeremy Sanders  
>> >> <jeremy+complangpyt... at jeremysanders.net> escribió:
>>
>> >> > It would be nice if Python created pipes that are properly  
>> >> inheritable by
>> >> > default by child processes, as they're mostly used for IPC.
>>
>> >> I'd say it is a bug in os.pipe implementation; they should be  
>> >> inheritable  
>> >> by default, as in posix (after all, the code is in "posixmodule.c").
>>
>> > The code looks like this:
>>
>> >    ok = CreatePipe(&read, &write, NULL, 0);
>> >    Py_END_ALLOW_THREADS
>> >    if (!ok)
>> >            return win32_error("CreatePipe", NULL);
>> >    read_fd = _open_osfhandle((Py_intptr_t)read, 0);
>> >    write_fd = _open_osfhandle((Py_intptr_t)write, 1);
>>
>> > 'If lpPipeAttributes is NULL, the handle cannot be inherited.'  You
>> > could populate a 'SECURITY_ATTRIBUTES' structure, or call
>> > DuplicateHandle on both of them.
>>
>> > A patch would look like this:
>>
>> > SECURITY_ATTRIBUTES sattribs;
>> > sattribs.nLength = sizeof(sattribs);
>> > sattribs.lpSecurityDescriptor = NULL;
>> > sattribs.bInheritHandle = TRUE;
>> > ok = CreatePipe(&read, &write, &sattribs, 0);
>>
>> Yes, that's exactly how os.popen does it (in posixmodule.c)
>>
>> > This still doesn't answer whether the file descriptor return by
>> > '_open_osfhandle' can be inherited too.
>>
>> It doesn't matter. The OS only cares about file handles, not C RTL  
>> structures.
>>
>> --
>> Gabriel Genellina
>
> Ah, I see.  Was it an executive decision about what is Pythonic, or
> just a bug?  Do you think the patch would be accepted?  I probably
> ought to mimic a small Python embedding to see if it needs anything
> else.

I don't know - I guess someone (years ago) blindly just replaced the
pipe() system call by a CreatePipe call without further analysis.

This is how I would summarize the issue:

Pros (of changing os.pipe() to return inheritable pipes):

- it isn't explicitely documented whether os.pipe() returns inheritable
pipes or not, so both versions are "right" according to the documentation.
- if someone relies on pipes being non-inheritable on Windows, that is
undocumented behaviour, and Python has the right to change it.
- the change would improve POSIX compatibility, it mimics what os.pipe()
does on those OS.
- inheritable pipes are less surprising for guys coming from other OS
- inheritable pipes are a lot more useful than non-inheritable ones when
doing IPC (probably its main usage).

Cons:

- os.pipe has behaved that way since long time ago.
- some programs *might* break, if they relied on pipes being
non-inheritable on Windows, even if that was undocumented behaviour.

-- 
Gabriel Genellina




More information about the Python-list mailing list