1#include "config.h" 2 3#if HAVE_MKDTEMP 4 5int 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 35char * 36mkdtemp(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