blob: f86bde2cbdf34de6f016102d40d310116897e557 (
plain)
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
80
|
/*
* 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.
*
* RCS: @(#) $Id: mkstemp.c,v 1.2 2009/05/12 20:26:04 dkf Exp $
*/
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.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 *template) /* Template for filename. */
{
static const char alphanumerics[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
register char *a, *b;
int fd, count, alphanumericsLen = strlen(alphanumerics); /* == 62 */
a = template + strlen(template);
while (a > template && *(a-1) == 'X') {
a--;
}
if (a == template) {
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 = random() / ((float) RAND_MAX);
*b = alphanumerics[(int)(r * alphanumericsLen)];
}
/*
* Template is now realized; try to open (with correct options).
*/
fd = open(template, O_RDWR|O_CREAT|O_EXCL, 0600);
} while (fd == -1 && errno == EEXIST && --count > 0);
return fd;
}
|