MKTEMP(3)

๐Ÿ“ฆ
version 15.1 ยท 2 versions
, in freebsd 15.1

๐Ÿ’… MKTEMP(3) โ€” like, the mktemp family, bestie โœจ

okay so this is a Library Functions Manual page for the mktemp squad, and it lives in the Standard C Library (libc, linked with -lc). buckle up, we're making temp files ๐ŸŽ€


โœจ 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);

int
mkostempsat(int dfd, char *template, int suffixlen, int oflags);

char *
mkdtemp(char *template);

#include <unistd.h>

int
mkstemps(char *template, int suffixlen);

๐ŸŒธ DESCRIPTION ๐ŸŒธ

the OG: mktemp()

so mktemp() takes the file name template you hand it and overwrites a chunk of it to make a file name. and like, this name is guaranteed not to exist at the moment you call the function, so it's literally ready for your app to use ๐Ÿซถ

your template can be any file name with some number of Xs tacked on the end โ€” for example /tmp/temp.XXXXXXXXXX. those trailing Xs get swapped out for a unique alphanumeric combo ๐Ÿ”ฅ

how many unique names can mktemp() give you? depends on how many Xs you put in, bestie. six Xs means mktemp() picks one out of 56800235584 (62 ** 6) possible temporary file names. yeah. that many ๐Ÿ’€

mkstemp() โ€” the upgrade

mkstemp() does the exact same replacement to the template and actually creates the template file, mode 0600, returning a file descriptor opened for reading and writing. the whole point? it avoids the race between testing whether a file exists and opening it for use. main character behavior, honestly ๐Ÿ‘‘

mkostemp() โ€” now with flags

mkostemp() is like mkstemp() but you get to specify extra open(2) flags (they live in <fcntl.h>). the permitted flags are:

O_APPEND, O_DIRECT, O_SHLOCK, O_EXLOCK, O_SYNC, O_CLOEXEC and O_CLOFORK

that's the whole list, don't try to sneak others in ๐Ÿ™ˆ

mkstemps() and mkostemps() โ€” suffix girlies

mkstemps() and mkostemps() act the same as mkstemp() and mkostemp() respectively, except they permit a suffix to exist in the template. your template should look like /tmp/tmpXXXXXXXXXXsuffix, and you tell mkstemps() / mkostemps() the length of that suffix string ๐ŸŽ€

mkostempsat() โ€” the directory-aware one

mkostempsat() acts the same as mkostemps() but takes an extra directory descriptor as a parameter. the temp file gets created relative to that corresponding directory โ€” or relative to the current working directory if you pass the special value AT_FDCWD โœจ

and if the template path is an absolute path? the dfd parameter is ignored and it behaves identically to mkostemps(). slay, consistency ๐Ÿ’…

mkdtemp() โ€” but a directory

mkdtemp() makes the same replacement to the template as in mktemp() and creates the template directory, mode 0700. that's it. that's the vibe ๐Ÿฆ‹


โญ RETURN VALUES โญ

  • mktemp() and mkdtemp() return a pointer to the template on success, and NULL on failure ๐Ÿ˜ญ
  • mkstemp(), mkostemp() mkstemps() and mkostemps() return -1 if no suitable file could be created

and if either call fails, an error code gets dropped into the global variable errno. we love a global variable ๐Ÿซ 


๐Ÿ’€ ERRORS ๐Ÿ’€

mkstemp(), mkostemp(), mkstemps(), mkostemps() and mkdtemp() may set errno to one of these:

  • [ENOTDIR] โ€” the pathname portion of the template is not an existing directory. like, that's not a folder, bestie ๐Ÿ™ˆ

mkostemp() and mkostemps() may also set errno to this:

  • [EINVAL] โ€” the oflags argument is invalid. you gave it something it can't work with ๐Ÿ’…

mkstemp(), mkostemp(), mkstemps(), mkostemps() and mkdtemp() may also set errno to any value specified by the stat(2) function ๐Ÿ‘‘

mkstemp(), mkostemp(), mkstemps() and mkostemps() may also set errno to any value specified by the open(2) function ๐Ÿ”ฅ

and mkdtemp() may also set errno to any value specified by the mkdir(2) function ๐ŸŒธ


๐ŸŽ€ NOTES ๐ŸŽ€

a very common problem that ends in a core dump: the programmer passes in a read-only string to mktemp(), mkstemp(), mkstemps() or mkdtemp(). this is super common with programs developed before ISO/IEC 9899:1990 (โ€œISO C90โ€) compilers were a normal thing ๐Ÿงš

for example, calling mkstemp() with an argument of "/tmp/tempfile.XXXXXXXXXX" will result in a core dump, because mkstemp() attempts to modify that string constant you so kindly handed it. do not do this ๐Ÿ˜ญ

also good to know: the mkdtemp(), mkstemp() and mktemp() function prototypes are also available from <unistd.h> ๐Ÿซถ

๐ŸŒˆ SEE ALSO ๐ŸŒˆ


๐Ÿ‘‘ STANDARDS ๐Ÿ‘‘

  • mkstemp() and mkdtemp() are expected to conform to IEEE Std 1003.1-2008 (โ€œPOSIX.1โ€) ๐Ÿ’–
  • mktemp() is expected to conform to IEEE Std 1003.1-2001 (โ€œPOSIX.1โ€) and is not specified by IEEE Std 1003.1-2008 (โ€œPOSIX.1โ€)
  • the mkostemp() function conforms to .
  • mkstemps(), mkostemps() and mkostempsat() do not conform to any standard. they're free spirits ๐Ÿฆ‹

โญ HISTORY โญ

  • a mktemp() function appeared in Version 7 AT&T UNIX
  • mkstemp() appeared in 4.4BSD
  • mkdtemp() first appeared in OpenBSD 2.2, and later in FreeBSD 3.2
  • mkstemps() first appeared in OpenBSD 2.4, and later in FreeBSD 3.4
  • mkostemp() and mkostemps() appeared in FreeBSD 10.0
  • mkostempsat() appeared in FreeBSD 13.0

like, a whole family tree. iconic lineage honestly ๐ŸŒณโœจ


๐Ÿšจ BUGS ๐Ÿšจ

okay this is the serious part, bestie, pay attention ๐Ÿ˜ค

this whole family of functions produces filenames that can be guessed โ€” though the risk is minimized when you use large numbers of Xs, because that increases the number of possible temporary filenames.

and that makes the race in mktemp() โ€” between testing for a file's existence (in the mktemp() function call) and opening it for use (later, in the user application) โ€” particularly dangerous from a security perspective. like, genuinely scary ๐Ÿšฉ

whenever it's possible, mkstemp(), mkostemp() or mkostempsat() should be used instead, since they do not have the race condition.

if mkstemp() cannot be used, the filename created by mktemp() should be created using the O_EXCL flag to open(2), and the return status of the call should be tested for failure. that way your program doesn't keep going blindly if an attacker has already created the file with the intention of manipulating or reading its contents ๐Ÿ’€


and that's the page!! this was Debian's MKTEMP(3), dated July 07, 2025 โ€” go make a temp file, but like, the safe way ๐Ÿ’…โœจ๐ŸŽ€

๐Ÿ“ฆ where this page comes from
  • freebsd 15.1: base 15.1
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms