classification
Title: inheritable pipes are unwieldy without os.pipe2
Type: Stage:
Components: Versions:
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: bukzor, pitrou, r.david.murray, vstinner
Priority: normal Keywords:

Created on 2014-10-24 18:25 by bukzor, last changed 2014-10-27 14:48 by vstinner.

Messages (6)
msg229947 - (view) Author: Buck Evan (bukzor) * Date: 2014-10-24 18:25
In order to make an inheritable pipe, the code is quite a bit different between posixes that implement pipe2 and those that don't (osx, mainly). I believe the officially-supported path is to call os.pipe() then os.setinheritable(). This seems objectionable since set_inheritable() code is invoked twice, where I'd prefer to invoke it zero times (or at most once).

Would it be acceptable to implement a pipe2 shim for those platforms?
If so, I'll (attempt to) provide a patch.

Alternatively, can we change the signature of os.pipe() to os.pipe(flags=O_CLOEXEC) ?  In my opinion, such a function could be implemented via pipe2 on those platforms that provide it, obviating any need for an os.pipe2.

Please tell me which patch to provide, if any.
msg229948 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2014-10-24 18:40
pipe2 can also be used to set O_NONBLOCK, so no, that specific API change wouldn't obsolete pipe2.  So, a shim for pipe2 would be the way to go, since that's currently the de-facto standard way of passing flags on pipe creation in unix land.  (The os module is usually a thin layer over OS services...for other modules we might design a more divergent API, but generally in the os module we do not.)
msg229953 - (view) Author: Buck Evan (bukzor) * Date: 2014-10-24 20:13
I notice that dup2 grew an `inheritable=True` argument in 3.4.
This might be a good precedent to use here, as a third option.
msg229963 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2014-10-24 22:39
> This seems objectionable since set_inheritable() code is invoked
> twice, where I'd prefer to invoke it zero times (or at most once).

Does it make a difference in the grand scheme of things? If you're forking a process, you're usually doing something heavy enough that two calls to set_inheritable() will end up invisible.
msg229987 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2014-10-25 06:31
os.dup2() is really a special case for inheritable file descriptors. See
the PEP 446.
msg230075 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2014-10-27 14:48
> Would it be acceptable to implement a pipe2 shim for those platforms?

If I understand correctly, you propose to add an option inheritable parameter to os.pipe():

def os.pipe(inheritable=False):
    ...

The PEP 446 was written to fix race conditions. os.pipe(inheritable=True) would create a race condition if another thread calls fork().

What is your use case? Please elaborate.

The subprocess module makes "pass_fds" file descriptors inheritables in a safe way.
History
Date User Action Args
2014-10-27 14:48:18vstinnersetmessages: + msg230075
2014-10-25 06:31:22vstinnersetmessages: + msg229987
2014-10-24 22:39:35pitrousetnosy: + pitrou
messages: + msg229963
2014-10-24 20:13:15bukzorsetmessages: + msg229953
2014-10-24 18:40:21r.david.murraysetnosy: + vstinner, r.david.murray
messages: + msg229948
2014-10-24 18:25:14bukzorcreate