Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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
bgColor#FFCCCC
/* ... */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
bgColor#FFCCCC
/* ... */
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
bgColor#FFcccc

/* ... */
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
bgColor#FFCCCC
/* ... */
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.

...