NAME
mktemp,
mkstemp,
mkstemps,
mkostemp,
mkostemps,
mkdtemp —
make unique temporary file
or directory name
LIBRARY
Standard C Library (libc, -lc)
SYNOPSIS
#include <stdlib.h>
char *
mktemp(
char
*template);
int
mkstemp(
char
*template);
int
mkostemp(
char
*template,
int
oflags);
int
mkostemps(
char
*template,
int
suffixlen,
int
oflags);
char *
mkdtemp(
char
*template);
#include <unistd.h>
int
mkstemps(
char
*template,
int
suffixlen);
DESCRIPTION
The
mktemp() function takes the given file name template and
overwrites a portion of it to create a file name. This file name is unique and
suitable for use by the application. The template may be any file name with
some number of ‘
X
’s appended to it, for
example
/tmp/temp.XXXXXX. The trailing
‘
X
’s are replaced with the current process
number and/or a unique letter combination. The number of unique file names
mktemp() can return depends on the number of
‘
X
’s provided. Although the
NetBSD implementation of the functions will accept any
number of trailing ‘
X
’s, for portability
reasons one should use only six. Using six
‘
X
’s will result in
mktemp() testing roughly 26 ** 6 (308915776) combinations.
The
mkstemp() function makes the same replacement to the
template and creates the template file, mode 0600, returning a file descriptor
opened for reading and writing. This avoids the race between testing for a
file's existence and opening it for use. The
mkostemp()
function is like
mkstemp() but allows specifying additional
open(2) flags (defined in
<fcntl.h>). The permitted flags are
O_APPEND
,
O_DIRECT
,
O_SHLOCK
,
O_EXLOCK
,
O_SYNC
and
O_CLOEXEC
.
The
mkstemps() and
mkostemps() functions act
the same as
mkstemp() and
mkostemp()
respectively, except they permit a suffix to exist in the template. The
template should be of the form
/tmp/tmpXXXXXXsuffix. The
mkstemps() and
mkostemps() function are
told the length of the suffix string.
The
mkdtemp() function is similar to
mkstemp(), but it creates a mode 0700 directory instead and
returns the path.
Please note that the permissions of the file or directory being created are
subject to the restrictions imposed by the
umask(2) system call. It may thus
happen that the created file is unreadable and/or unwritable.
RETURN VALUES
The
mktemp() and
mkdtemp() functions return
a pointer to the template on success and
NULL
on
failure. The
mkstemp(),
mkostemp(),
mkstemps() and
mkostemps() functions
returns -1 if no suitable file could be created. If either call fails an error
code is placed in the global variable
errno.
EXAMPLES
Quite often a programmer will want to replace a use of
mktemp() with
mkstemp(), usually to avoid
the problems described above. Doing this correctly requires a good
understanding of the code in question.
For instance, code of this form:
char sfn[15] = "";
FILE *sfp;
strlcpy(sfn, "/tmp/ed.XXXXXX", sizeof sfn);
if (mktemp(sfn) == NULL || (sfp = fopen(sfn, "w+")) == NULL) {
fprintf(stderr, "%s: %s\n", sfn, strerror(errno));
return (NULL);
}
return (sfp);
should be rewritten like this:
char sfn[15] = "";
FILE *sfp;
int fd = -1;
strlcpy(sfn, "/tmp/ed.XXXXXX", sizeof sfn);
if ((fd = mkstemp(sfn)) == -1 ||
(sfp = fdopen(fd, "w+")) == NULL) {
if (fd != -1) {
unlink(sfn);
close(fd);
}
fprintf(stderr, "%s: %s\n", sfn, strerror(errno));
return (NULL);
}
return (sfp);
Often one will find code which uses
mktemp() very early on,
perhaps to globally initialize the template nicely, but the code which calls
open(2) or
fopen(3) on that filename will
occur much later. (In almost all cases, the use of
fopen(3) will mean that the flags
O_CREAT
|
O_EXCL
are not given
to
open(2), and thus a symbolic
link race becomes possible, hence making necessary the use of
fdopen(3) as seen above).
Furthermore, one must be careful about code which opens, closes, and then
re-opens the file in question. Finally, one must ensure that upon error the
temporary file is removed correctly.
There are also cases where modifying the code to use
mktemp(),
in concert with
open(2) using the
flags
O_CREAT
|
O_EXCL
, is
better, as long as the code retries a new template if
open(2) fails with an
errno of
EEXIST
.
ERRORS
The
mkstemp(),
mkostemp(),
mkstemps(),
mkostemps() and
mkdtemp() functions may set
errno to
one of the following values:
-
-
- [
ENOTDIR
]
- The pathname portion of the template is not an existing
directory.
The
mktemp(),
mkstemp() and
mkdtemp() functions may also set
errno
to any value specified by the
stat(2) function.
The
mkstemp() function may also set
errno to any value specified by the
open(2) function.
The
mkdtemp() function may also set
errno to any value specified by the
mkdir(2) function.
SEE ALSO
chmod(2),
getpid(2),
open(2),
stat(2),
umask(2)
STANDARDS
The
mktemp() conforms to
IEEE Std 1003.1-2001
(“POSIX.1”). It was however removed from the specification
in the
IEEE Std 1003.1-2008 (“POSIX.1”)
revision. The
mkstemp() and
mkdtemp()
functions conform to
IEEE Std 1003.1-2004
(“POSIX.1”) and
IEEE Std 1003.1-2008
(“POSIX.1”), respectively.
HISTORY
A
mktemp() function appeared in
Version 7 AT&T UNIX.
The
mkstemp() function appeared in
4.4BSD.
The
mkdtemp() function appeared in
NetBSD
1.4. The
mkstemps() function first appeared in
OpenBSD 2.4, and later in
FreeBSD
3.4 and
NetBSD 7.0. The
mkostemp() and
mkostemps() functions
appeared in
FreeBSD 10.0 and
NetBSD
7.0.
BUGS
For
mktemp() there is an obvious race between file name
selection and file creation and deletion: the program is typically written to
call
tmpnam(3),
tempnam(3), or
mktemp(). Subsequently, the program calls
open(2) or
fopen(3) and erroneously opens a
file (or symbolic link, fifo or other device) that the attacker has created in
the expected file location. Hence
mkstemp() is recommended,
since it atomically creates the file. An attacker can guess the filenames
produced by
mktemp(). Whenever it is possible,
mkstemp() or
mkdtemp() should be used
instead.
For this reason,
ld(1) will output a
warning message whenever it links code that uses
mktemp().
The
mkdtemp() function is nonstandard and should not be used
if portability is required.
SECURITY CONSIDERATIONS
The use of
mktemp() should generally be avoided, as a hostile
process can exploit a race condition in the time between the generation of a
temporary filename by
mktemp() and the invoker's use of the
temporary name. A link-time warning will be issued advising the use of
mkstemp() or
mkdtemp() instead.