classification
Title: os.pipe should return inheritable descriptors (Windows)
Type: behavior Stage:
Components: Library (Lib), Windows Versions: Python 3.0, Python 3.1, Python 2.7, Python 2.6
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: tim.golden Nosy List: Daniel.Goertzen, castironpi, gagenellina, jnoller, tim.golden
Priority: normal Keywords: patch

Created on 2008-12-21 02:15 by castironpi, last changed 2010-08-11 12:37 by Daniel.Goertzen.

Files
File name Uploaded Description Edit
os_pipe_test.py castironpi, 2008-12-21 02:15 test showing subprocess inheriting handle
inheritable_pipes.diff gagenellina, 2008-12-26 23:57 patch to posixmodule.c including test case and documentation updates. review
Messages (4)
msg78136 - (view) Author: Aaron Brady (castironpi) Date: 2008-12-21 02:15
os.pipe should return inheritable descriptors on Windows.

Patch below, test attached.  New pipe() returns descriptors, which
cannot be inherited.  However, their permissions are set correctly, so
msvcrt.get_osfhandle and msvcrt.open_osfhandle can be used to obtain an
inheritable handle.

Docs should contain a note to the effect.  'On Windows, use
msvcrt.get_osfhandle to obtain a handle to the descriptor which can be
inherited.  In a subprocess, use msvcrt.open_osfhandle to obtain a new
corresponding descriptor.'

--- posixmodule_orig.c  2008-12-20 20:01:38.296875000 -0600
+++ posixmodule_new.c   2008-12-20 20:01:54.359375000 -0600
@@ -6481,8 +6481,12 @@
        HANDLE read, write;
        int read_fd, write_fd;
        BOOL ok;
+       SECURITY_ATTRIBUTES sAttribs;
        Py_BEGIN_ALLOW_THREADS
-       ok = CreatePipe(&read, &write, NULL, 0);
+       sAttribs.nLength = sizeof( sAttribs );
+       sAttribs.lpSecurityDescriptor = NULL;
+       sAttribs.bInheritHandle = TRUE;
+       ok = CreatePipe(&read, &write, &sAttribs, 0);
        Py_END_ALLOW_THREADS
        if (!ok)
                return win32_error("CreatePipe", NULL);
msg78166 - (view) Author: Gabriel Genellina (gagenellina) Date: 2008-12-22 03:03
From the thread in c.l.p: 

Pros (of changing os.pipe() to return inheritable pipes):
 
- as it isn't explicitely documented whether os.pipe() returns 
inheritable pipes or not, both versions are "right" according to the 
documentation.

- if someone relies on pipes being non-inheritable on Windows (why?), 
this is undocumented behaviour, and Python has the right to change it.

- 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.
msg78321 - (view) Author: Gabriel Genellina (gagenellina) Date: 2008-12-26 23:57
Patch to posixmodule.c including test case and documentation updates.
Note: I've only run the tests on Windows.
msg79844 - (view) Author: Aaron Brady (castironpi) Date: 2009-01-14 08:41
This is currently accomplished in 'multiprocessing.forking' with a
'duplicate' function.

Use (line #213):
    rfd, wfd = os.pipe()
    
    # get handle for read end of the pipe and make it inheritable
    rhandle = duplicate(msvcrt.get_osfhandle(rfd), inheritable=True)

Definition (line #192).

Should it be included in the public interface and documented, or perhaps
a public entry point to it made?
History
Date User Action Args
2010-08-11 12:37:31Daniel.Goertzensetnosy: + Daniel.Goertzen
2010-08-06 15:07:27tim.goldensetassignee: tim.golden

nosy: + tim.golden
2009-01-19 16:38:54jnollersetnosy: + jnoller
2009-01-14 08:41:50castironpisetmessages: + msg79844
2008-12-26 23:57:33gagenellinasetfiles: + inheritable_pipes.diff
keywords: + patch
messages: + msg78321
2008-12-22 03:03:24gagenellinasetnosy: + gagenellina
messages: + msg78166
2008-12-21 02:15:24castironpicreate