From patchwork Mon Jun 26 11:47:38 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Schwab X-Patchwork-Id: 21262 Received: (qmail 82689 invoked by alias); 26 Jun 2017 11:47:42 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 82679 invoked by uid 89); 26 Jun 2017 11:47:41 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 spammy=unnamed X-HELO: mx1.suse.de From: Andreas Schwab To: libc-alpha@sourceware.org Subject: [PATCH] Implement tmpfile with O_TMPFILE (bug 21530) X-Yow: MERYL STREEP is my obstetrician! Date: Mon, 26 Jun 2017 13:47:38 +0200 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux) MIME-Version: 1.0 If the kernel or the file system does not support O_TMPFILE fall back to creating a temporary file based on tmpnam. [BZ #21530] * stdio-common/tmpfile.c (tmpfile) [O_TMPFILE]: Try opening an unnamed file first. --- stdio-common/tmpfile.c | 51 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/stdio-common/tmpfile.c b/stdio-common/tmpfile.c index e6030be0af..5505d6f571 100644 --- a/stdio-common/tmpfile.c +++ b/stdio-common/tmpfile.c @@ -18,6 +18,8 @@ #include #include +#include +#include #include #include @@ -27,30 +29,51 @@ #endif -/* This returns a new stream opened on a temporary file (generated - by tmpnam). The file is opened with mode "w+b" (binary read/write). - If we couldn't generate a unique filename or the file couldn't - be opened, NULL is returned. */ +/* This returns a new stream opened on an unnamed file (if supported) or a + temporary file (generated by tmpnam). The file is opened with mode + "w+b" (binary read/write). If we couldn't generate a unique filename + or the file couldn't be opened, NULL is returned. */ FILE * tmpfile (void) { - char buf[FILENAME_MAX]; - int fd; + int fd = -1; FILE *f; - - if (__path_search (buf, FILENAME_MAX, NULL, "tmpf", 0)) - return NULL; int flags = 0; #ifdef FLAGS flags = FLAGS; #endif - fd = __gen_tempname (buf, 0, flags, __GT_FILE); + +#ifdef O_TMPFILE + fd = __open (P_tmpdir, O_RDWR | O_TMPFILE | O_EXCL | flags, + S_IRUSR | S_IWUSR); + if (fd < 0 && errno == ENOENT && strcmp (P_tmpdir, "/tmp") != 0) + fd = __open ("/tmp", O_RDWR | O_TMPFILE | O_EXCL | flags, + S_IRUSR | S_IWUSR); if (fd < 0) - return NULL; + { + if (errno != EISDIR && errno != EOPNOTSUPP) + return NULL; - /* Note that this relies on the Unix semantics that - a file is not really removed until it is closed. */ - (void) __unlink (buf); + /* Either O_TMPFILE is unknown to the kernel, or the file system + does not support it. */ + } +#endif + if (fd < 0) + { + char buf[FILENAME_MAX]; + + if (__path_search (buf, FILENAME_MAX, NULL, "tmpf", 0)) + return NULL; + fd = __gen_tempname (buf, 0, flags, __GT_FILE); + + if (fd >= 0) + /* Note that this relies on the Unix semantics that + a file is not really removed until it is closed. */ + (void) __unlink (buf); + } + + if (fd < 0) + return NULL; if ((f = __fdopen (fd, "w+b")) == NULL) __close (fd);