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