Made-Up File Names

Many moons ago, I coded a file-renaming utility. It allows me to shuffle chapter names for documents used in my books, renaming a whole batch at once without overwriting existing filenames. It couldn’t happen if I didn’t know about the mktemp() function.

Defined in the unistd.h header file, the mktemp() function generates a temporary filename. Technically, it generates a string, one that’s unique but based on a pattern or template you provide. Here’s how I use it in my file-renaming utility:

t = mktemp("gbXXXXXX");

The immediate string constant "gbXXXXXX" provides the filename template. The X’s in the string are replaced by random characters. The resulting string is saved in char pointer variable t. The code moves on to use that temporary filename.

Here’s a sample program:

#include <stdio.h>
#include <unistd.h>

int main()
{
    char template[] = "tempXXXX";
    char *tempname;

    tempname = mktemp(template);
    printf("Temporary filename is '%s' or '%s'\n",
            tempname,template);

    return(0);
}

Sample run:

Temporary filename is 'tempmCcZ' or 'tempmCcZ'

When you run it again, you get different output:

Temporary filename is 'tempzGUA' or 'tempzGUA'

In the code, the mktemp() function takes the template, tempXXXX and replaces the uppercase X characters with other, random characters. The result is returned as referenced in the tempname pointer, but the buffer itself is also changed, as shown in the output.

Because the mktemp() function overwrites the template, it creates an interesting problem when you must generate more than one temporary filename based on the same pattern. To resolve this issue, you retain the template by copying it into a temporary buffer, such as temp[] used in this example:

#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(void)
{
    char temp[9];
    char template[] = "tempXXXX";
    char *t;
    int x;

    for(x=0;x<10;x++)
    {
        strcpy(temp,template);
        t = mktemp(temp);
        puts(t);
    }

    return(0);
}

The strcpy() function at Line 14 copies the template into the temp buffer. Then mktemp() at Line 15 uses that buffer to generate the temporary filename. Here’s the output:

tempAnWr
tempdVoi
tempGPwb
tempvFm8
temp8Pkl
temp2scJ
temp9cFf
tempoOcn
tempyher
temphAwd

These filenames are available for use in your code, guaranteed by the function not to exist. Variations on the mktemp() function take the action further and actually create the temporary file — or even a directory. You can read more details in the man pages.

One more point! The mktemp() function returns the NULL pointer when it’s unable to do its job. For the code you plan on running in the wild, ensure that you check for NULL after the mktemp() function returns its value.

2 thoughts on “Made-Up File Names

  1. There are a few things I don’t understand about mktemp:

    What do you do if you want to uses Xs in your filenames?

    How does it avoid generating the same name twice? Or does it rely on the name it generates being used to save a file before being called again?

    Can you specify a directory for it to check for filename uniqueness?

  2. 1. I suppose the answer relies on why you’d want an X in a temporary filename.

    2. I don’t know. The source is available, of course, so I could dig in and see what magic it’s using to concoct the names, especially for multiple calls.

    3. The mktemp() function has several siblings, though I forget what each one does. I believe one creates the file for you.

    The function does return NULL when it’s incapable of concocting a temporary filename, which means some sort of checking is done somewhere on the line.

Leave a Reply