PEP 433: updates

This commit is contained in:
Victor Stinner 2013-01-18 12:45:30 +01:00
parent e34084ed52
commit 647aa4e22b
1 changed files with 60 additions and 19 deletions

View File

@ -1,5 +1,5 @@
PEP: 433 PEP: 433
Title: Add cloexec parameter to functions creating file descriptors Title: Easier suppression of file descriptor inheritance
Version: $Revision$ Version: $Revision$
Last-Modified: $Date$ Last-Modified: $Date$
Author: Victor Stinner <victor.stinner@gmail.com> Author: Victor Stinner <victor.stinner@gmail.com>
@ -176,10 +176,12 @@ functions creating file descriptors in the Python standard library. If
the parameter is ``True``, the close-on-exec flag will be set on the the parameter is ``True``, the close-on-exec flag will be set on the
new file descriptor. new file descriptor.
Add a new function: Add a new functions:
* ``os.set_cloexec(fd: int, cloexec: bool)``: set or clear the * ``os.get_cloexec(fd:int) -> bool``: get the
close-on-exec flag of a file descriptor close-on-exec flag of a file descriptor. Not available on all platforms.
* ``os.set_cloexec(fd:int, cloexec:bool=True)``: set or clear the
close-on-exec flag on a file descriptor. Not available on all platforms.
Add a new optional ``cloexec`` parameter to: Add a new optional ``cloexec`` parameter to:
@ -227,8 +229,16 @@ Drawbacks:
Alternatives Alternatives
============ ============
Set the close-on-exec flag by default Bikeshedding on the name of the new parameter
------------------------------------- ---------------------------------------------
* ``inherit``, ``inherited``: closer to Windows definition
* ``sensitive``
* ``sterile``: "Does not produce offspring."
Enable file descriptor inheritance by default
---------------------------------------------
Set the close-on-exec flag by default on new file descriptors created Set the close-on-exec flag by default on new file descriptors created
by Python. This alternative just changes the default value of the new by Python. This alternative just changes the default value of the new
@ -427,15 +437,47 @@ XXX Benchmark the overhead for these 4 methods. XXX
Implementation Implementation
============== ==============
os.set_cloexec(fd, cloexec) os.get_cloexec(fd)
--------------------------- ------------------
Best-effort by definition. Pseudo-code:: Get the close-on-exec flag of a file descriptor.
Pseudo-code::
if os.name == 'nt':
def get_cloexec(fd):
handle = _winapi._get_osfhandle(fd);
flags = _winapi.GetHandleInformation(handle)
return not(flags & _winapi.HANDLE_FLAG_INHERIT)
else:
try:
import fcntl
except ImportError:
pass
else:
def get_cloexec(fd):
flags = fcntl.fcntl(fd, fcntl.F_GETFD)
return bool(flags & fcntl.FD_CLOEXEC)
os.set_cloexec(fd, cloexec=True)
--------------------------------
Set or clear the close-on-exec flag on a file descriptor. The flag
is set after the creation of the file descriptor and so it is not
atomic.
Pseudo-code::
if os.name == 'nt': if os.name == 'nt':
def set_cloexec(fd, cloexec=True): def set_cloexec(fd, cloexec=True):
SetHandleInformation(fd, HANDLE_FLAG_INHERIT, handle = _winapi._get_osfhandle(fd);
int(cloexec)) mask = _winapi.HANDLE_FLAG_INHERIT
if cloexec:
flags = 0
else:
flags = mask
_winapi.SetHandleInformation(handle, mask, flags)
else: else:
fnctl = None fnctl = None
ioctl = None ioctl = None
@ -460,11 +502,6 @@ Best-effort by definition. Pseudo-code::
else: else:
flags &= ~FD_CLOEXEC flags &= ~FD_CLOEXEC
fcntl.fcntl(fd, fcntl.F_SETFD, flags) fcntl.fcntl(fd, fcntl.F_SETFD, flags)
else:
def set_cloexec(fd, cloexec=True):
raise NotImplementedError(
"close-on-exec flag is not supported "
"on your platform")
ioctl is preferred over fcntl because it requires only one syscall, ioctl is preferred over fcntl because it requires only one syscall,
instead of two syscalls for fcntl. instead of two syscalls for fcntl.
@ -501,13 +538,15 @@ os.dup2()
os.pipe() os.pipe()
--------- ---------
* Windows: ``_pipe()`` with ``O_NOINHERIT`` flag [atomic] * Windows: ``CreatePipe()`` with ``SECURITY_ATTRIBUTES.bInheritHandle=TRUE``,
or ``_pipe()`` with ``O_NOINHERIT`` flag [atomic]
* ``pipe2()`` with ``O_CLOEXEC`` flag [atomic] * ``pipe2()`` with ``O_CLOEXEC`` flag [atomic]
* ``pipe()`` + ``os.set_cloexec(fd, True)`` [best-effort] * ``pipe()`` + ``os.set_cloexec(fd, True)`` [best-effort]
socket.socket() socket.socket()
--------------- ---------------
* Windows: ``WSASocket()`` with ``WSA_FLAG_NO_HANDLE_INHERIT`` flag
* ``socket()`` with ``SOCK_CLOEXEC`` flag [atomic] * ``socket()`` with ``SOCK_CLOEXEC`` flag [atomic]
* ``socket()`` + ``os.set_cloexec(fd, True)`` [best-effort] * ``socket()`` + ``os.set_cloexec(fd, True)`` [best-effort]
@ -579,8 +618,10 @@ New flags:
* ``O_CLOEXEC``: available on Linux (2.6.23+), FreeBSD (8.3+), * ``O_CLOEXEC``: available on Linux (2.6.23+), FreeBSD (8.3+),
OpenBSD 5.0, QNX, BeOS, next NetBSD release (6.1?). This flag is OpenBSD 5.0, QNX, BeOS, next NetBSD release (6.1?). This flag is
part of POSIX.1-2008. part of POSIX.1-2008.
* ``socket()``: ``SOCK_CLOEXEC`` flag, available on Linux 2.6.27+, * ``SOCK_CLOEXEC`` flag for ``socket()`` and ``socketpair()``,
OpenBSD 5.2, NetBSD 6.0. available on Linux 2.6.27+, OpenBSD 5.2, NetBSD 6.0.
* ``WSA_FLAG_NO_HANDLE_INHERIT`` flag for ``WSASocket()``: supported on
Windows 7 with SP1, Windows Server 2008 R2 with SP1, and later
* ``fcntl()``: ``F_DUPFD_CLOEXEC`` flag, available on Linux 2.6.24+, * ``fcntl()``: ``F_DUPFD_CLOEXEC`` flag, available on Linux 2.6.24+,
OpenBSD 5.0, FreeBSD 9.1, NetBSD 6.0. This flag is part of OpenBSD 5.0, FreeBSD 9.1, NetBSD 6.0. This flag is part of
POSIX.1-2008. POSIX.1-2008.