PEP 433: change the proposal to sys.setdefaultcloexec(cloexec: bool)

This commit is contained in:
Victor Stinner 2013-01-29 17:43:17 +01:00
parent 36d505a562
commit 6b8569c21e
1 changed files with 188 additions and 206 deletions

View File

@ -13,10 +13,14 @@ Python-Version: 3.4
Abstract Abstract
======== ========
This PEP proposes to add a new optional parameter ``cloexec`` on Add a new optional *cloexec* parameter on functions creating file
functions creating file descriptors in the Python standard library. If descriptors, add different ways to change default values of this
the parameter is ``True``, the close-on-exec flag will be set on the parameter, and add four new functions:
new file descriptor.
* ``os.get_cloexec(fd)``
* ``os.set_cloexec(fd, cloexec=True)``
* ``sys.getdefaultcloexec()``
* ``sys.setdefaultcloexec(cloexec=True)``
Rationale Rationale
@ -25,38 +29,42 @@ Rationale
A file descriptor has a close-on-exec flag which indicates if the file A file descriptor has a close-on-exec flag which indicates if the file
descriptor will be inherited or not. descriptor will be inherited or not.
On UNIX, the file descriptor will be closed on the execution of child processes On UNIX, if the close-on-exec flag is set, the file descriptor is not
if the close-on-exec flag is set, the file descriptor is inherited by child inherited: it will be closed at the execution of child processes;
processes if the flag is cleared. otherwise the file descriptor is inherited by child processes.
On Windows, the file descriptor is not inherited if the close-on-exec flag is On Windows, if the close-on-exec flag is set, the file descriptor is not
set, the file descriptor is inherited by child processes if the flag is cleared inherited; the file descriptor is inherited by child processes if the
and if ``CreateProcess()`` is called with the *bInheritHandles* parameter set close-on-exec flag is cleared and if ``CreateProcess()`` is called with
to ``TRUE`` (when ``subprocess.Popen`` is created with ``close_fds=False`` for the *bInheritHandles* parameter set to ``TRUE`` (when
example). ``subprocess.Popen`` is created with ``close_fds=False`` for example).
Windows does now have "close-on-exec" flag but an inherance flag which
is just the opposite value. For example, setting close-on-exec flag set
means clearing the ``HANDLE_FLAG_INHERIT`` flag of an handle.
Status in Python 3.3 Status in Python 3.3
-------------------- --------------------
On UNIX, the subprocess module closes file descriptors greater than 2 by On UNIX, the subprocess module closes file descriptors greater than 2 by
default since Python 3.2 [#subprocess_close]_. All file descriptors created by default since Python 3.2 [#subprocess_close]_. All file descriptors
the parent process are automatically closed in the child process. created by the parent process are automatically closed in the child
process.
``xmlrpc.server.SimpleXMLRPCServer`` sets the close-on-exec flag of ``xmlrpc.server.SimpleXMLRPCServer`` sets the close-on-exec flag of
the listening socket, the parent class ``socketserver.BaseServer`` the listening socket, the parent class ``socketserver.TCPServer``
does not set this flag. does not set this flag.
There are other cases creating a subprocess or executing a new program There are other cases creating a subprocess or executing a new program
where file descriptors are not closed: functions of the os.spawn*() where file descriptors are not closed: functions of the ``os.spawn*()``
family and third party modules calling ``exec()`` or ``fork()`` + and the ``os.exec*()`` families and third party modules calling
``exec()``. In this case, file descriptors are shared between the ``exec()`` or ``fork()`` + ``exec()``. In this case, file descriptors
parent and the child processes which is usually unexpected and causes are shared between the parent and the child processes which is usually
various issues. unexpected and causes various issues.
This PEP proposes to continue the work started with the change in the This PEP proposes to continue the work started with the change in the
subprocess, to fix the issue in any code, and not just code using subprocess in Python 3.2, to fix the issue in any code, and not just
subprocess. code using subprocess.
Inherited file descriptors issues Inherited file descriptors issues
@ -66,15 +74,14 @@ Closing the file descriptor in the parent process does not close the
related resource (file, socket, ...) because it is still open in the related resource (file, socket, ...) because it is still open in the
child process. child process.
The listening socket of TCPServer is not closed on ``exec()``: the The listening socket of TCPServer is not closed on ``exec()``: the child
child process is able to get connection from new clients; if the process is able to get connection from new clients; if the parent closes
parent closes the listening socket and create a new listening socket the listening socket and create a new listening socket on the same
on the same address, it would get an "address already is used" error. address, it would get an "address already is used" error.
Not closing file descriptors can lead to resource exhaustion: even if Not closing file descriptors can lead to resource exhaustion: even if
the parent closes all files, creating a new file descriptor may fail the parent closes all files, creating a new file descriptor may fail
with "too many files" because files are still open in the child with "too many files" because files are still open in the child process.
process.
See also the following issues: See also the following issues:
@ -160,20 +167,6 @@ standard library. Third party modules not using the standard library
should be modified to conform to this PEP. The new should be modified to conform to this PEP. The new
``os.set_cloexec()`` function can be used for example. ``os.set_cloexec()`` function can be used for example.
Impacted functions:
* ``os.forkpty()``
* ``http.server.CGIHTTPRequestHandler.run_cgi()``
Impacted modules:
* ``multiprocessing``
* ``socketserver``
* ``subprocess``
* ``tempfile``
* ``xmlrpc.server``
* Maybe: ``signal``, ``threading``
XXX Should ``subprocess.Popen`` clear the close-on-exec flag on file XXX Should ``subprocess.Popen`` clear the close-on-exec flag on file
XXX descriptors of the constructor the ``pass_fds`` parameter? XXX descriptors of the constructor the ``pass_fds`` parameter?
@ -185,78 +178,93 @@ XXX descriptors of the constructor the ``pass_fds`` parameter?
Proposal Proposal
======== ========
This PEP proposes to add a new optional parameter ``cloexec`` on Add a new optional *cloexec* parameter on functions creating file
functions creating file descriptors in the Python standard library. If descriptors and different ways to change default values of this
the parameter is ``True``, the close-on-exec flag will be set on the parameter.
new file descriptor.
Add a new functions: Add new functions:
* ``os.get_cloexec(fd:int) -> bool``: get the * ``os.get_cloexec(fd:int) -> bool``: get the
close-on-exec flag of a file descriptor. Not available on all platforms. 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 * ``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. close-on-exec flag on a file descriptor. Not available on all
platforms.
* ``sys.getdefaultcloexec() -> bool``: get the current default value
of the *cloexec* parameter
* ``sys.setdefaultcloexec(cloexec: bool=True)``: set the default value
of the *cloexec* parameter
Add a new optional ``cloexec`` parameter to: Add a new optional *cloexec* parameter to:
* ``open()``: ``os.fdopen()`` is indirectly modified * ``asyncore.dispatcher.create_socket()``
* ``os.dup()``, ``os.dup2()`` * ``io.FileIO``
* ``io.open()``
* ``open()``
* ``os.dup()``
* ``os.dup2()``
* ``os.fdopen()``
* ``os.open()``
* ``os.openpty()``
* ``os.pipe()`` * ``os.pipe()``
* ``socket.socket()``, ``socket.socketpair()``, * ``select.devpoll()``
``socket.socket.accept()`` * ``select.epoll()``
* Maybe also: ``os.open()``, ``os.openpty()`` * ``select.kqueue()``
* TODO: * ``socket.socket()``
* ``socket.socket.accept()``
* ``socket.socket.dup()``
* ``socket.socket.fromfd``
* ``socket.socketpair()``
* ``select.devpoll()`` The default value of the *cloexec* parameter is
* ``select.poll()`` ``sys.getdefaultcloexec()``.
* ``select.epoll()``
* ``select.kqueue()``
* ``socket.socket.recvmsg()``: use ``MSG_CMSG_CLOEXEC``,
or ``os.set_cloexec()``
The default value of the ``cloexec`` parameter is ``False`` to keep the Add a new command line option ``-e`` and an environment variable
backward compatibility. ``PYTHONCLOEXEC`` to the set close-on-exec flag by default.
The close-on-exec flag will not be set on file descriptors 0 (stdin), All functions creating file descriptors in the standard library must
1 (stdout) and 2 (stderr), because these files are expected to be respect the default *cloexec* parameter (``sys.getdefaultcloexec()``).
inherited. It would still be possible to set close-on-exec flag
explicitly using ``os.set_cloexec()``.
Drawbacks: File descriptors 0 (stdin), 1 (stdout) and 2 (stderr) are expected to be
inherited, but Python does not handle them differently. When
``os.dup2()`` is used to replace standard streams, ``cloexec=False``
must be specified explicitly.
* Many functions of the Python standard library creating file Drawbacks of the proposal:
descriptors cannot be changed by this proposal, because adding
a ``cloexec`` optional parameter would be surprising and too many * It is not more possible to know if the close-on-exec flag will be
functions would need it. For example, ``os.urandom()`` uses a set or not on a newly created file descriptor just by reading the
temporary file on UNIX, but it calls a function of Windows API on source code.
Windows. Adding a ``cloexec`` parameter to ``os.urandom()`` would * If the inherance of a file descriptor matters, the *cloexec*
not make sense. See `Enable file descriptor inheritance by default`_ parameter must now be specified explicitly, or the library or the
for an incomplete list of functions creating file descriptors. application will not work depending on the default value of the
* Checking if a module creates file descriptors is difficult. For *cloexec* parameter.
example, ``os.urandom()`` creates a file descriptor on UNIX to read
``/dev/urandom`` (and closes it at exit), whereas it is implemented
using a function call on Windows. It is not possible to control
close-on-exec flag of the file descriptor used by ``os.urandom()``,
because ``os.urandom()`` API does not allow it.
Alternatives Alternatives
============ ============
Bikeshedding on the name of the new parameter Enable inherance by default and no configurable default
--------------------------------------------- -------------------------------------------------------
* ``inherit``, ``inherited``: closer to Windows definition Add a new optional parameter *cloexec* on functions creating file
* ``sensitive`` descriptors. The default value of the *cloexec* parameter is ``False``,
* ``sterile``: "Does not produce offspring." and this default cannot be changed. No file descriptor inherance by
default is also the default on POSIX and on Windows. This alternative is
the most convervative option.
This option does solve issues listed in the `Rationale`_
section, it only provides an helper to fix them. All functions creating
file descriptors have to be modified to set *cloexec=True* in each
module used by an application to fix all these issues.
Enable file descriptor inheritance by default Disable inheritance by default
--------------------------------------------- ------------------------------
Set the close-on-exec flag by default on new file descriptors created This alternative is based on the proposal: the only difference is that
by Python. This alternative just changes the default value of the new the default value of the *cloexec* parameter is ``True`` (instead of
``cloexec`` parameter. ``False``).
If a file must be inherited by child processes, ``cloexec=False`` If a file must be inherited by child processes, ``cloexec=False``
parameter can be used. parameter can be used.
@ -266,27 +274,6 @@ specify which file descriptors must be inherited. The close-on-exec
flag of these file descriptors must be changed with flag of these file descriptors must be changed with
``os.set_cloexec()``. ``os.set_cloexec()``.
Example of functions creating file descriptors which will be modified
to set close-on-exec flag:
* ``os.urandom()`` (on UNIX)
* ``curses.window.getwin()``, ``curses.window.putwin()``
* ``mmap.mmap()`` (if ``MAP_ANONYMOUS`` is not defined)
* ``oss.open()``
* ``Modules/main.c``: ``RunStartupFile()``
* ``Python/pythonrun.c``: ``PyRun_SimpleFileExFlags()``
* ``Modules/getpath.c``: ``search_for_exec_prefix()``
* ``Modules/zipimport.c``: ``read_directory()``
* ``Modules/_ssl.c``: ``load_dh_params()``
* ``PC/getpathp.c``: ``calculate_path()``
* ``Python/errors.c``: ``PyErr_ProgramText()``
* ``Python/import.c``: ``imp_load_dynamic()``
* TODO: ``PC/_msi.c``
Many functions are impacted indirectly by this alternative. Examples:
* ``logging.FileHandler``
Advantages of setting close-on-exec flag by default: Advantages of setting close-on-exec flag by default:
* There are far more programs that are bitten by FD inheritance upon * There are far more programs that are bitten by FD inheritance upon
@ -296,6 +283,9 @@ Advantages of setting close-on-exec flag by default:
Drawbacks of setting close-on-exec flag by default: Drawbacks of setting close-on-exec flag by default:
* It violates the principle of least surprise. Developers using the
os module may expect that Python respects the POSIX standard and so
that close-on-exec flag is not set by default.
* The os module is written as a thin wrapper to system calls (to * The os module is written as a thin wrapper to system calls (to
functions of the C standard library). If atomic flags to set functions of the C standard library). If atomic flags to set
close-on-exec flag are not supported (see `Appendix: Operating close-on-exec flag are not supported (see `Appendix: Operating
@ -303,9 +293,6 @@ Drawbacks of setting close-on-exec flag by default:
system calls (see `Performances`_ section). system calls (see `Performances`_ section).
* Extra system calls, if any, may slow down Python: see * Extra system calls, if any, may slow down Python: see
`Performances`_. `Performances`_.
* It violates the principle of least surprise. Developers using the
os module may expect that Python respects the POSIX standard and so
that close-on-exec flag is not set by default.
Backward compatibility: only a few programs rely on inherance of file Backward compatibility: only a few programs rely on inherance of file
descriptors, and they only pass a few file descriptors, usually just descriptors, and they only pass a few file descriptors, usually just
@ -319,48 +306,19 @@ parameter of Popen constructor. So it possible that these programs will
not need any fix if they use the ``subprocess`` module. not need any fix if they use the ``subprocess`` module.
Add a function to set close-on-exec flag by default
---------------------------------------------------
An alternative is to add also a function to change globally the
default behaviour. It would be possible to set close-on-exec flag for
the whole application including all modules and the Python standard
library. This alternative is based on the `Proposal`_ and adds extra
changes.
New functions, command line argument and environment variable:
* ``sys.getdefaultcloexec() -> bool``: get the default value of the
*cloexec* parameter
* ``sys.setdefaultcloexec()``, ``-e`` command line option, ``PYTHONCLOEXEC``
environment variable (if set): set the default value of the *cloexec*
parameter to ``True``
The major change is that the default value of the ``cloexec`` parameter
is ``sys.getdefaultcloexec()``, instead of ``False``.
When ``sys.setdefaultcloexec()`` is called to set close-on-exec by default, we
have the same drawbacks as the `Enable file descriptor inheritance by default`_
alternative.
There are additionnal drawbacks of having two behaviours depending on
``sys.getdefaultcloexec()`` value:
* It is not more possible to know if the close-on-exec flag will be
set or not just by reading the source code.
Close file descriptors after fork Close file descriptors after fork
--------------------------------- ---------------------------------
This PEP does not fix issues with applications using ``fork()`` This PEP does not fix issues with applications using ``fork()``
without ``exec()``. Python needs a generic process to register without ``exec()``. Python needs a generic process to register
callbacks which would be called after a fork, see `Add an 'atfork' callbacks which would be called after a fork, see `#16500:
module`_. Such registry could be used to close file descriptors just Add an atfork module`_. Such registry could be used to close file
after a ``fork()``. descriptors just after a ``fork()``.
Drawbacks: Drawbacks:
* It does not solve the problem on Windows: ``fork()`` does not exist
on Windows
* This alternative does not solve the problem for programs using * This alternative does not solve the problem for programs using
``exec()`` without ``fork()``. ``exec()`` without ``fork()``.
* A third party module may call directly the C function ``fork()`` * A third party module may call directly the C function ``fork()``
@ -390,6 +348,16 @@ F_SETFD, FD_CLOEXEC)``. With Visual Studio, fopen() accepts a "N"
flag which uses ``O_NOINHERIT``. flag which uses ``O_NOINHERIT``.
Bikeshedding on the name of the new parameter
---------------------------------------------
* ``inherit``, ``inherited``: closer to Windows definition
* ``sensitive``
* ``sterile``: "Does not produce offspring."
Applications using inherance of file descriptors Applications using inherance of file descriptors
================================================ ================================================
@ -402,19 +370,20 @@ No user complained about this behavior change yet.
Network servers using fork may want to pass the client socket to the Network servers using fork may want to pass the client socket to the
child process. For example, on UNIX a CGI server pass the socket child process. For example, on UNIX a CGI server pass the socket
client through file descriptors 0 (stdin) and 1 (stdout) using client through file descriptors 0 (stdin) and 1 (stdout) using
``dup2()``. This specific case is not impacted by this PEP because the ``dup2()``.
close-on-exec flag is never set on file descriptors smaller than 3.
To access a restricted resource like creating a socket listening on a To access a restricted resource like creating a socket listening on a
TCP port lower than 1024 or reading a file containing sensitive data TCP port lower than 1024 or reading a file containing sensitive data
like passwords, a common practice is: start as the root user, create a like passwords, a common practice is: start as the root user, create a
file descriptor, create a child process, pass the file descriptor to file descriptor, create a child process, drop privileges (ex: change the
the child process and exit. Security is very important in such use current user), pass the file descriptor to the child process and exit
case: leaking another file descriptor would be a critical security the parent process.
vulnerability (see `Security`_). The root process may not exit but
monitors the child process instead, and restarts a new child process Security is very important in such use case: leaking another file
and pass the same file descriptor if the previous child process descriptor would be a critical security vulnerability (see `Security`_).
crashed. The root process may not exit but monitors the child process instead,
and restarts a new child process and pass the same file descriptor if
the previous child process crashed.
Example of programs taking file descriptors from the parent process Example of programs taking file descriptors from the parent process
using a command line option: using a command line option:
@ -436,13 +405,13 @@ Setting close-on-exec flag may require additional system calls for
each creation of new file descriptors. The number of additional system each creation of new file descriptors. The number of additional system
calls depends on the method used to set the flag: calls depends on the method used to set the flag:
* ``O_NOINHERIT``: no additionnal system call * ``O_NOINHERIT``: no additional system call
* ``O_CLOEXEC``: one addition system call, but only at the creation * ``O_CLOEXEC``: one additional system call, but only at the creation
of the first file descriptor, to check if the flag is supported. If of the first file descriptor, to check if the flag is supported. If
no, Python has to fallback to the next method. the flag is not supported, Python has to fallback to the next method.
* ``ioctl(fd, FIOCLEX)``: one addition system call per file * ``ioctl(fd, FIOCLEX)``: one additional system call per file
descriptor descriptor
* ``fcntl(fd, F_SETFD, flags)``: two addition system calls per file * ``fcntl(fd, F_SETFD, flags)``: two additional system calls per file
descriptor, one to get old flags and one to set new flags descriptor, one to get old flags and one to set new flags
On Linux, setting the close-on-flag has a low overhead on performances. On Linux, setting the close-on-flag has a low overhead on performances.
@ -560,8 +529,9 @@ os.dup2()
os.pipe() os.pipe()
--------- ---------
* Windows: ``CreatePipe()`` with ``SECURITY_ATTRIBUTES.bInheritHandle=TRUE``, * Windows: ``CreatePipe()`` with
or ``_pipe()`` with ``O_NOINHERIT`` flag [atomic] ``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]
@ -569,6 +539,7 @@ socket.socket()
--------------- ---------------
* Windows: ``WSASocket()`` with ``WSA_FLAG_NO_HANDLE_INHERIT`` flag * Windows: ``WSASocket()`` with ``WSA_FLAG_NO_HANDLE_INHERIT`` flag
[atomic]
* ``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]
@ -603,56 +574,63 @@ processes".
For example, it is supported by ``open()`` and ``_pipe()``. For example, it is supported by ``open()`` and ``_pipe()``.
The value of the flag can be modified using: The flag can be cleared using
``SetHandleInformation(fd, HANDLE_FLAG_INHERIT, 1)``. ``SetHandleInformation(fd, HANDLE_FLAG_INHERIT, 0)``.
``CreateProcess()`` has an ``bInheritHandles`` parameter: if it is ``CreateProcess()`` has an ``bInheritHandles`` parameter: if it is
FALSE, the handles are not inherited. It is used by ``FALSE``, the handles are not inherited. If it is ``TRUE``, handles
``subprocess.Popen`` with ``close_fds`` option. with ``HANDLE_FLAG_INHERIT`` flag set are inherited.
``subprocess.Popen`` uses ``close_fds`` option to define
``bInheritHandles``.
fcntl
-----
Functions:
* ``fcntl(fd, F_GETFD)``
* ``fcntl(fd, F_SETFD, flags | FD_CLOEXEC)``
Availability: AIX, Digital UNIX, FreeBSD, HP-UX, IRIX, Linux, Mac OS
X, OpenBSD, Solaris, SunOS, Unicos.
ioctl ioctl
----- -----
Functions: Functions:
* ``ioctl(fd, FIOCLEX, 0)`` sets close-on-exec flag * ``ioctl(fd, FIOCLEX, 0)``: set the close-on-exec flag
* ``ioctl(fd, FIONCLEX, 0)`` clears close-on-exec flag * ``ioctl(fd, FIONCLEX, 0)``: clear the close-on-exec flag
Availability: Linux, Mac OS X, QNX, NetBSD, OpenBSD, FreeBSD. Availability: Linux, Mac OS X, QNX, NetBSD, OpenBSD, FreeBSD.
fcntl
-----
Functions:
* ``flags = fcntl(fd, F_GETFD); fcntl(fd, F_SETFD, flags | FD_CLOEXEC)``:
set the close-on-exec flag
* ``flags = fcntl(fd, F_GETFD); fcntl(fd, F_SETFD, flags & ~FD_CLOEXEC)``:
clear the close-on-exec flag
Availability: AIX, Digital UNIX, FreeBSD, HP-UX, IRIX, Linux, Mac OS
X, OpenBSD, Solaris, SunOS, Unicos.
Atomic flags Atomic flags
------------ ------------
New flags: 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.
* ``SOCK_CLOEXEC`` flag for ``socket()`` and ``socketpair()``, * ``SOCK_CLOEXEC`` flag for ``socket()`` and ``socketpair()``,
available on Linux 2.6.27+, 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 * ``WSA_FLAG_NO_HANDLE_INHERIT`` flag for ``WSASocket()``: supported
Windows 7 with SP1, Windows Server 2008 R2 with SP1, and later 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.
* ``recvmsg()``: ``MSG_CMSG_CLOEXEC``, available on Linux 2.6.23+, * ``recvmsg()``: ``MSG_CMSG_CLOEXEC``, available on Linux 2.6.23,
NetBSD 6.0. NetBSD 6.0.
On Linux older than 2.6.23, ``O_CLOEXEC`` flag is simply ignored. So On Linux older than 2.6.23, ``O_CLOEXEC`` flag is simply ignored. So
we have to check that the flag is supported by calling ``fcntl()``. If we have to check that the flag is supported by calling ``fcntl()``. If
it does not work, we have to set the flag using ``fcntl()``. it does not work, we have to set the flag using ``ioctl()`` or
``fcntl()``.
On Linux older than 2.6.27, if the ``SOCK_CLOEXEC`` flag is set in the On Linux older than 2.6.27, if the ``SOCK_CLOEXEC`` flag is set in the
socket type, ``socket()`` or ``socketpair()`` fail and ``errno`` is set socket type, ``socket()`` or ``socketpair()`` fail and ``errno`` is set
@ -660,9 +638,9 @@ to ``EINVAL``.
New functions: New functions:
* ``dup3()``: available on Linux 2.6.27+ (and glibc 2.9) * ``dup3()``: available on Linux 2.6.27 (and glibc 2.9)
* ``pipe2()``: available on Linux 2.6.27+ (and glibc 2.9) * ``pipe2()``: available on Linux 2.6.27 (and glibc 2.9)
* ``accept4()``: available on Linux 2.6.28+ (and glibc 2.10) * ``accept4()``: available on Linux 2.6.28 (and glibc 2.10)
If ``accept4()`` is called on Linux older than 2.6.28, ``accept4()`` If ``accept4()`` is called on Linux older than 2.6.28, ``accept4()``
returns ``-1`` (fail) and ``errno`` is set to ``ENOSYS``. returns ``-1`` (fail) and ``errno`` is set to ``ENOSYS``.
@ -683,30 +661,34 @@ Links:
Python issues: Python issues:
* `open() does not able to set flags, such as O_CLOEXEC * `#10115: Support accept4() for atomic setting of flags at socket
creation <http://bugs.python.org/issue10115>`_
* `#12105: open() does not able to set flags, such as O_CLOEXEC
<http://bugs.python.org/issue12105>`_ <http://bugs.python.org/issue12105>`_
* `Add "e" mode to open(): close-and-exec (O_CLOEXEC) / O_NOINHERIT * `#12107: TCP listening sockets created without FD_CLOEXEC flag
<http://bugs.python.org/issue16850>`_
* `TCP listening sockets created without FD_CLOEXEC flag
<http://bugs.python.org/issue12107>`_ <http://bugs.python.org/issue12107>`_
* `Use O_CLOEXEC in the tempfile module * `#16500: Add an atfork module
<http://bugs.python.org/issue16860>`_
* `Support accept4() for atomic setting of flags at socket creation
<http://bugs.python.org/issue10115>`_
* `Add an 'atfork' module
<http://bugs.python.org/issue16500>`_ <http://bugs.python.org/issue16500>`_
* `Implementation of the PEP 433 * `#16850: Add "e" mode to open(): close-and-exec
(O_CLOEXEC) / O_NOINHERIT <http://bugs.python.org/issue16850>`_
* `#16860: Use O_CLOEXEC in the tempfile module
<http://bugs.python.org/issue16860>`_
* `#17036: Implementation of the PEP 433
<http://bugs.python.org/issue17036>`_ <http://bugs.python.org/issue17036>`_
* `#16946: subprocess: _close_open_fd_range_safe() does not set
close-on-exec flag on Linux < 2.6.23 if O_CLOEXEC is defined
<http://bugs.python.org/issue16946>`_
* `#17070: PEP 433: Use the new cloexec to improve security and avoid
bugs <http://bugs.python.org/issue17070>`_
Ruby: Ruby:
* `Set FD_CLOEXEC for all fds (except 0, 1, 2) * `Set FD_CLOEXEC for all fds (except 0, 1, 2)
<http://bugs.ruby-lang.org/issues/5041>`_ <http://bugs.ruby-lang.org/issues/5041>`_
* `O_CLOEXEC flag missing for Kernel::open * `O_CLOEXEC flag missing for Kernel::open
<http://bugs.ruby-lang.org/issues/1291>`_: <http://bugs.ruby-lang.org/issues/1291>`_: the
`commit reverted `commit was reverted later
<http://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/31643>`_ <http://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/31643>`_
later
Footnotes Footnotes
========= =========