1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
|
/*
* mkstemp.c --
*
* Source code for the "mkstemp" library routine.
*
* Copyright (c) 2009 Donal K. Fellows
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
/*
*----------------------------------------------------------------------
*
* mkstemp --
*
* Create an open temporary file from a template.
*
* Results:
* A file descriptor, or -1 (with errno set) in the case of an error.
*
* Side effects:
* The template is updated to contain the real filename.
*
*----------------------------------------------------------------------
*/
int
mkstemp(
char *tmpl) /* Template for filename. */
{
static const char alphanumerics[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
char *a, *b;
int fd, count, alphanumericsLen = strlen(alphanumerics); /* == 62 */
a = tmpl + strlen(tmpl);
while (a > tmpl && *(a-1) == 'X') {
a--;
}
if (a == tmpl) {
errno = ENOENT;
return -1;
}
/*
* We'll only try up to 10 times; after that, we're suffering from enemy
* action and should let the caller know.
*/
count = 10;
do {
/*
* Replace the X's in the original template with random alphanumeric
* digits.
*/
for (b=a ; *b ; b++) {
float r = rand() / ((float) RAND_MAX);
*b = alphanumerics[(int)(r * alphanumericsLen)];
}
/*
* Template is now realized; try to open (with correct options).
*/
fd = open(tmpl, O_RDWR|O_CREAT|O_EXCL, 0600);
} while (fd == -1 && errno == EEXIST && --count > 0);
return fd;
}
|