...
Wiki Markup |
---|
The C99 {{tmpnam()}} function generates a string that is a valid filename and that is not the same as the name of an existing file \[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\]. Files created using strings generated by the {{tmpnam()}} function are temporary in that their names should not collide with those generated by conventional naming rules for the [implementation|BB. Definitions#implementation]. The function is potentially capable of generating {{TMP_MAX}} different strings, but any or all of them may already be in use by existing files. If the argument is not a null pointer, it is assumed to point to an array of at least {{L_tmpnam}} chars; the {{tmpnam()}} function writes its result in that array and returns the argument as its value. |
Code Block | ||
---|---|---|
| ||
/* ... */char temp_file_name[L_tmpnam]; if (tmpnam(temp_file_name)) { /* temp_file_name may refer to an existing file */ t_file = fopen(temp_file_name,"wb+"); if (!t_file) { /* Handle Error */ } } /* ... */ |
Non-Compliant Code Example: tmpnam_s()
(ISO/IEC TR 24731-1)
...
If implemented, this reduces the space for unique names and increases the predictability of the resulting names. But in general, TR 24731-1 does not establish any criteria for predictability of names.
Code Block | ||
---|---|---|
| ||
/* ... */ FILE *file_ptr; char filename[L_tmpnam_s]; if (tmpnam_s(filename, L_tmpnam_s) != 0) { /* Handle Error */ } Â /* A TOCTOU race condition exists here */ if (!fopen_s(&file_ptr, filename, "wb+")) { /* Handle Error */ } /* ... */ |
Implementation Details
For Microsoft Visual Studio 2005, the name generated by tmpnam_s
consists of a program-generated filename and, after the first call to tmpnam_s()
, a file extension of sequential numbers in base 32 (.1-.1vvvvvu, when TMP_MAX_S
in stdio.h
is INT_MAX
).
...
The POSIX function mktemp()
takes a given filename template and overwrites a portion of it to create a filename. The template may be any filename with some number of Xs appended to it (for example, /tmp/temp.XXXXXX
). The trailing Xs are replaced with the current process number and/or a unique letter combination. The number of unique filenames mktemp()
can return depends on the number of Xs provided.
Code Block | ||
---|---|---|
| ||
/* ... */ int fd; char temp_name[] = "/tmp/temp-XXXXXX"; if (mktemp(temp_name) == NULL) { /* Handle Error */ } if /* A TOCTOU race condition exists here */ if ((fd = open(temp_name, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, 0600)) == -1) { /* Handle Error */ } /* ... */ |
The mktemp()
function has been marked LEGACY in the Open Group Base Specifications Issue 6.
...
Most historic implementations provide only a limited number of possible temporary filenames (usually 26) before filenames are recycled.
Code Block | ||
---|---|---|
| ||
/* ... */ FILE *tempfile if ((fd = tmpfile(void); if (tempfile)) == NULL) { /* handleHandle error conditionError */ } /* ... */ |
Wiki Markup |
---|
The {{tmpfile()}} function may not be compliant with \[[TMP33-C. Temporary files must be removed before the program exits]\] for implementations where the temporary file is not removed if the program terminates abnormally. |
...