changeset: 91033:4b51a992cb70 user: Victor Stinner date: Thu Jun 05 14:27:45 2014 +0200 files: Doc/library/tempfile.rst Lib/tempfile.py Misc/NEWS description: Issue #21515: tempfile.TemporaryFile now uses os.O_TMPFILE flag is available diff -r 782c3b4cbc88 -r 4b51a992cb70 Doc/library/tempfile.rst --- a/Doc/library/tempfile.rst Thu Jun 05 12:07:14 2014 +0200 +++ b/Doc/library/tempfile.rst Thu Jun 05 14:27:45 2014 +0200 @@ -54,6 +54,13 @@ underlying true file object. This file-like object can be used in a :keyword:`with` statement, just like a normal file. + The :py:data:`os.O_TMPFILE` flag is used if it is available and works + (Linux-specific, require Linux kernel 3.11 or later). + + .. versionchanged:: 3.5 + + The :py:data:`os.O_TMPFILE` flag is now used if available. + .. function:: NamedTemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix='', prefix='tmp', dir=None, delete=True) diff -r 782c3b4cbc88 -r 4b51a992cb70 Lib/tempfile.py --- a/Lib/tempfile.py Thu Jun 05 12:07:14 2014 +0200 +++ b/Lib/tempfile.py Thu Jun 05 14:27:45 2014 +0200 @@ -473,6 +473,11 @@ TemporaryFile = NamedTemporaryFile else: + # Is the O_TMPFILE flag available and does it work? + # The flag is set to False if os.open(dir, os.O_TMPFILE) raises an + # IsADirectoryError exception + _O_TMPFILE_WORKS = hasattr(_os, 'O_TMPFILE') + def TemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix="", prefix=template, dir=None): @@ -488,11 +493,32 @@ Returns an object with a file-like interface. The file has no name, and will cease to exist when it is closed. """ + global _O_TMPFILE_WORKS if dir is None: dir = gettempdir() flags = _bin_openflags + if _O_TMPFILE_WORKS: + try: + flags2 = (flags | _os.O_TMPFILE) & ~_os.O_CREAT + fd = _os.open(dir, flags2, 0o600) + except IsADirectoryError: + # Linux kernel older than 3.11 ignores O_TMPFILE flag. + # Set flag to None to not try again. + _O_TMPFILE_WORKS = False + except OSError: + # The filesystem of the directory does not support O_TMPFILE. + # For example, OSError(95, 'Operation not supported'). + pass + else: + try: + return _io.open(fd, mode, buffering=buffering, + newline=newline, encoding=encoding) + except: + _os.close(fd) + raise + # Fallback to _mkstemp_inner(). (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags) try: diff -r 782c3b4cbc88 -r 4b51a992cb70 Misc/NEWS --- a/Misc/NEWS Thu Jun 05 12:07:14 2014 +0200 +++ b/Misc/NEWS Thu Jun 05 14:27:45 2014 +0200 @@ -88,6 +88,8 @@ Library ------- +- Issue #21515: tempfile.TemporaryFile now uses os.O_TMPFILE flag is available. + - Issue #21618: The subprocess module could fail to close open fds that were inherited by the calling process and already higher than POSIX resource limits would otherwise allow. On systems with a functioning /proc/self/fd