1 #include "config.h" 2 3 #if HAVE_MKDTEMP 4 5 int dummy; 6 7 #else 8 9 /* $Id: compat_mkdtemp.c,v 1.2 2015/10/06 18:32:19 schwarze Exp $ */ 10 /* 11 * Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org> 12 * 13 * Permission to use, copy, modify, and distribute this software for any 14 * purpose with or without fee is hereby granted, provided that the above 15 * copyright notice and this permission notice appear in all copies. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 18 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 20 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 21 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 22 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 23 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 24 * 25 * The algorithm of this function is inspired by OpenBSD mkdtemp(3) 26 * by Theo de Raadt and Todd Miller, but the code differs. 27 */ 28 29 #include <sys/stat.h> 30 #include <errno.h> 31 #include <limits.h> 32 #include <stdlib.h> 33 #include <string.h> 34 35 char * 36 mkdtemp(char *path) 37 { 38 char *start, *cp; 39 unsigned int tries; 40 41 start = strchr(path, '\0'); 42 while (start > path && start[-1] == 'X') 43 start--; 44 45 for (tries = INT_MAX; tries; tries--) { 46 if (mktemp(path) == NULL) { 47 errno = EEXIST; 48 return NULL; 49 } 50 if (mkdir(path, S_IRUSR | S_IWUSR | S_IXUSR) == 0) 51 return path; 52 if (errno != EEXIST) 53 return NULL; 54 for (cp = start; *cp != '\0'; cp++) 55 *cp = 'X'; 56 } 57 errno = EEXIST; 58 return NULL; 59 } 60 61 #endif 62