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