]> granicus.if.org Git - python/commitdiff
Issue #21515: tempfile.TemporaryFile now uses os.O_TMPFILE flag is available
authorVictor Stinner <victor.stinner@gmail.com>
Thu, 5 Jun 2014 12:27:45 +0000 (14:27 +0200)
committerVictor Stinner <victor.stinner@gmail.com>
Thu, 5 Jun 2014 12:27:45 +0000 (14:27 +0200)
Doc/library/tempfile.rst
Lib/tempfile.py
Misc/NEWS

index d78159d64bc49e2c7f545ac7658dffd26415f8c6..4ad7d9c555b0e1a203c7896c2529921080064292 100644 (file)
@@ -54,6 +54,13 @@ The module defines the following user-callable items:
    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)
 
index f0e25fc2d5492f42ad9e75bbc585dd62790458b4..b26e50e8e427a0dcba8295562964ae72dab7d7df 100644 (file)
@@ -473,6 +473,11 @@ if _os.name != 'posix' or _os.sys.platform == 'cygwin':
     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 @@ else:
         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:
index ffc172765e4f77bd9a77c5f2ae24baab32c78989..8e5fb3ad750cc712b11114ef2a0b67692943a605 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -88,6 +88,8 @@ Core and Builtins
 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