From 647aa4e22b420dbd8272bc1dc94a0689d1183a92 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 18 Jan 2013 12:45:30 +0100 Subject: [PATCH] PEP 433: updates --- pep-0433.txt | 79 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 60 insertions(+), 19 deletions(-) diff --git a/pep-0433.txt b/pep-0433.txt index f72cb5863..21f4a8e71 100644 --- a/pep-0433.txt +++ b/pep-0433.txt @@ -1,5 +1,5 @@ PEP: 433 -Title: Add cloexec parameter to functions creating file descriptors +Title: Easier suppression of file descriptor inheritance Version: $Revision$ Last-Modified: $Date$ Author: Victor Stinner @@ -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 new file descriptor. -Add a new function: +Add a new functions: - * ``os.set_cloexec(fd: int, cloexec: bool)``: set or clear the - close-on-exec flag of a file descriptor + * ``os.get_cloexec(fd:int) -> bool``: get the + 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: @@ -227,8 +229,16 @@ Drawbacks: 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 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 ============== -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': def set_cloexec(fd, cloexec=True): - SetHandleInformation(fd, HANDLE_FLAG_INHERIT, - int(cloexec)) + handle = _winapi._get_osfhandle(fd); + mask = _winapi.HANDLE_FLAG_INHERIT + if cloexec: + flags = 0 + else: + flags = mask + _winapi.SetHandleInformation(handle, mask, flags) else: fnctl = None ioctl = None @@ -460,11 +502,6 @@ Best-effort by definition. Pseudo-code:: else: flags &= ~FD_CLOEXEC 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, instead of two syscalls for fcntl. @@ -501,13 +538,15 @@ os.dup2() 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] * ``pipe()`` + ``os.set_cloexec(fd, True)`` [best-effort] socket.socket() --------------- + * Windows: ``WSASocket()`` with ``WSA_FLAG_NO_HANDLE_INHERIT`` flag * ``socket()`` with ``SOCK_CLOEXEC`` flag [atomic] * ``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+), OpenBSD 5.0, QNX, BeOS, next NetBSD release (6.1?). This flag is part of POSIX.1-2008. - * ``socket()``: ``SOCK_CLOEXEC`` flag, available on Linux 2.6.27+, - OpenBSD 5.2, NetBSD 6.0. + * ``SOCK_CLOEXEC`` flag for ``socket()`` and ``socketpair()``, + 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+, OpenBSD 5.0, FreeBSD 9.1, NetBSD 6.0. This flag is part of POSIX.1-2008.