subprocess.Popen inheriting

Aaron Brady castironpi at gmail.com
Fri Dec 19 02:45:21 CET 2008


On Dec 18, 6:11 pm, "Gabriel Genellina" <gagsl-... at yahoo.com.ar>
wrote:
> En Thu, 18 Dec 2008 08:35:58 -0200, Aaron Brady <castiro... 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

Hi,

Microsoft has this example:

http://msdn.microsoft.com/en-us/library/aa298531.aspx

It creates two descriptors (not handles) with '_pipe'.  Then it spawns
a subprocess using 'spawnl', which correctly inherits a descriptor.
So, if 'Popen' could mimic 'spawnl', then 'os.pipe', and consequently,
'os.read', 'os.write', &c. could stay as is.





More information about the Python-list mailing list