libite 2.6.1
tempfile.c
Go to the documentation of this file.
1/* A secure tmpfile() replacement.
2 *
3 * Copyright (c) 2015-2021 Joachim Wiberg <troglobit@gmail.com>
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
24
25#include <errno.h>
26#include <paths.h>
27#include <fcntl.h> /* O_TMPFILE requires -D_GNU_SOURCE */
28#include <stdio.h> /* fdopen() */
29#include <stdlib.h> /* mkostemp() */
30#include <sys/stat.h> /* umask() */
31
32static FILE *fallback(void)
33{
34 char nm[15] = _PATH_TMP "XXXXXXXX";
35 int fd;
36
37 fd = mkostemp(nm, O_CLOEXEC);
38 if (-1 == fd)
39 return NULL;
40
41 return fdopen(fd, "w+");
42}
43
59FILE *tempfile(void)
60{
61#ifdef O_TMPFILE /* Only on Linux, with fairly recent (G)LIBC */
62 int fd;
63 mode_t oldmask;
64
65 oldmask = umask(0077);
66 fd = open(_PATH_TMP, O_TMPFILE | O_RDWR | O_EXCL | O_CLOEXEC, S_IRUSR | S_IWUSR);
67 umask(oldmask);
68 if (-1 == fd) {
69 if (errno == EOPNOTSUPP)
70 return fallback();
71
72 return NULL;
73 }
74
75 return fdopen(fd, "w+");
76#else
77 return fallback();
78#endif
79}
80
FILE * tempfile(void)
Definition tempfile.c:59