PostgreSQL Source Code
git master
Loading...
Searching...
No Matches
mkdtemp.c
Go to the documentation of this file.
1
/*-------------------------------------------------------------------------
2
*
3
* mkdtemp.c
4
* create a mode-0700 temporary directory
5
*
6
* Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7
*
8
*
9
* IDENTIFICATION
10
* src/port/mkdtemp.c
11
*
12
* This code was taken from NetBSD to provide an implementation for platforms
13
* that lack it. (Among compatibly-licensed implementations, the OpenBSD
14
* version better resists denial-of-service attacks. However, it has a
15
* cryptographic dependency.) The NetBSD copyright terms follow.
16
*-------------------------------------------------------------------------
17
*/
18
19
#include "
c.h
"
20
21
#define _DIAGASSERT(x) do {} while (0)
22
23
24
/* $NetBSD: gettemp.c,v 1.17 2014/01/21 19:09:48 seanb Exp $ */
25
26
/*
27
* Copyright (c) 1987, 1993
28
* The Regents of the University of California. All rights reserved.
29
*
30
* Redistribution and use in source and binary forms, with or without
31
* modification, are permitted provided that the following conditions
32
* are met:
33
* 1. Redistributions of source code must retain the above copyright
34
* notice, this list of conditions and the following disclaimer.
35
* 2. Redistributions in binary form must reproduce the above copyright
36
* notice, this list of conditions and the following disclaimer in the
37
* documentation and/or other materials provided with the distribution.
38
* 3. Neither the name of the University nor the names of its contributors
39
* may be used to endorse or promote products derived from this software
40
* without specific prior written permission.
41
*
42
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
43
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
46
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
48
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
50
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
51
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52
* SUCH DAMAGE.
53
*/
54
55
#if HAVE_NBTOOL_CONFIG_H
56
#include "nbtool_config.h"
57
#endif
58
59
#if !HAVE_NBTOOL_CONFIG_H || !HAVE_MKSTEMP || !HAVE_MKDTEMP
60
61
#ifdef NOT_POSTGRESQL
62
#include <sys/cdefs.h>
63
#if defined(LIBC_SCCS) && !defined(lint)
64
#if 0
65
static
char
sccsid
[] =
"@(#)mktemp.c 8.1 (Berkeley) 6/4/93"
;
66
#else
67
__RCSID
(
"$NetBSD: gettemp.c,v 1.17 2014/01/21 19:09:48 seanb Exp $"
);
68
#endif
69
#endif
/* LIBC_SCCS and not lint */
70
#endif
71
72
#include <sys/types.h>
73
#include <sys/stat.h>
74
75
#include <assert.h>
76
#include <ctype.h>
77
#include <errno.h>
78
#include <fcntl.h>
79
#include <stdio.h>
80
#include <stdlib.h>
81
#include <
unistd.h
>
82
83
#ifdef NOT_POSTGRESQL
84
#if HAVE_NBTOOL_CONFIG_H
85
#define GETTEMP __nbcompat_gettemp
86
#else
87
#include "reentrant.h"
88
#include "local.h"
89
#define GETTEMP __gettemp
90
#endif
91
#endif
92
93
static
int
94
GETTEMP
(
char
*path,
int
*
doopen
,
int
domkdir
)
95
{
96
char
*
start
,
97
*
trv
;
98
struct
stat
sbuf
;
99
u_int
pid;
100
101
/*
102
* To guarantee multiple calls generate unique names even if the file is
103
* not created. 676 different possibilities with 7 or more X's, 26 with 6
104
* or less.
105
*/
106
static
char
xtra
[2] =
"aa"
;
107
int
xcnt = 0;
108
109
_DIAGASSERT
(path !=
NULL
);
110
/* doopen may be NULL */
111
112
pid =
getpid
();
113
114
/* Move to end of path and count trailing X's. */
115
for
(
trv
= path; *
trv
; ++
trv
)
116
if
(*
trv
==
'X'
)
117
xcnt++;
118
else
119
xcnt = 0;
120
121
/* Use at least one from xtra. Use 2 if more than 6 X's. */
122
if
(xcnt > 0)
123
{
124
*--
trv
=
xtra
[0];
125
xcnt--;
126
}
127
if
(xcnt > 5)
128
{
129
*--
trv
=
xtra
[1];
130
xcnt--;
131
}
132
133
/* Set remaining X's to pid digits with 0's to the left. */
134
for
(; xcnt > 0; xcnt--)
135
{
136
*--
trv
= (pid % 10) +
'0'
;
137
pid /= 10;
138
}
139
140
/* update xtra for next call. */
141
if
(
xtra
[0] !=
'z'
)
142
xtra
[0]++;
143
else
144
{
145
xtra
[0] =
'a'
;
146
if
(
xtra
[1] !=
'z'
)
147
xtra
[1]++;
148
else
149
xtra
[1] =
'a'
;
150
}
151
152
/*
153
* check the target directory; if you have six X's and it doesn't exist
154
* this runs for a *very* long time.
155
*/
156
for
(
start
=
trv
+ 1;; --
trv
)
157
{
158
if
(
trv
<= path)
159
break
;
160
if
(*
trv
==
'/'
)
161
{
162
int
e
;
163
164
*
trv
=
'\0'
;
165
e
=
stat
(path, &
sbuf
);
166
*
trv
=
'/'
;
167
if
(
e
== -1)
168
return
doopen
==
NULL
&& !
domkdir
;
169
if
(!
S_ISDIR
(
sbuf
.st_mode))
170
{
171
errno
=
ENOTDIR
;
172
return
doopen
==
NULL
&& !
domkdir
;
173
}
174
break
;
175
}
176
}
177
178
for
(;;)
179
{
180
if
(
doopen
)
181
{
182
if
((*
doopen
=
183
open
(path,
O_CREAT
|
O_EXCL
|
O_RDWR
, 0600)) >= 0)
184
return
1;
185
if
(
errno
!=
EEXIST
)
186
return
0;
187
}
188
else
if
(
domkdir
)
189
{
190
if
(
mkdir
(path, 0700) >= 0)
191
return
1;
192
if
(
errno
!=
EEXIST
)
193
return
0;
194
}
195
else
if
(
lstat
(path, &
sbuf
))
196
return
errno
==
ENOENT
? 1 : 0;
197
198
/* tricky little algorithm for backward compatibility */
199
for
(
trv
=
start
;;)
200
{
201
if
(!*
trv
)
202
return
0;
203
if
(*
trv
==
'z'
)
204
*
trv
++ =
'a'
;
205
else
206
{
207
if
(
isdigit
((
unsigned
char
) *
trv
))
208
*
trv
=
'a'
;
209
else
210
++*
trv
;
211
break
;
212
}
213
}
214
}
215
/* NOTREACHED */
216
}
217
218
#endif
/* !HAVE_NBTOOL_CONFIG_H || !HAVE_MKSTEMP ||
219
* !HAVE_MKDTEMP */
220
221
222
/* $NetBSD: mkdtemp.c,v 1.11 2012/03/15 18:22:30 christos Exp $ */
223
224
/*
225
* Copyright (c) 1987, 1993
226
* The Regents of the University of California. All rights reserved.
227
*
228
* Redistribution and use in source and binary forms, with or without
229
* modification, are permitted provided that the following conditions
230
* are met:
231
* 1. Redistributions of source code must retain the above copyright
232
* notice, this list of conditions and the following disclaimer.
233
* 2. Redistributions in binary form must reproduce the above copyright
234
* notice, this list of conditions and the following disclaimer in the
235
* documentation and/or other materials provided with the distribution.
236
* 3. Neither the name of the University nor the names of its contributors
237
* may be used to endorse or promote products derived from this software
238
* without specific prior written permission.
239
*
240
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
241
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
242
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
243
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
244
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
245
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
246
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
247
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
248
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
249
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
250
* SUCH DAMAGE.
251
*/
252
253
#if HAVE_NBTOOL_CONFIG_H
254
#include "nbtool_config.h"
255
#endif
256
257
#if !HAVE_NBTOOL_CONFIG_H || !HAVE_MKDTEMP
258
259
#ifdef NOT_POSTGRESQL
260
261
#include <sys/cdefs.h>
262
#if defined(LIBC_SCCS) && !defined(lint)
263
#if 0
264
static
char
sccsid
[] =
"@(#)mktemp.c 8.1 (Berkeley) 6/4/93"
;
265
#else
266
__RCSID
(
"$NetBSD: mkdtemp.c,v 1.11 2012/03/15 18:22:30 christos Exp $"
);
267
#endif
268
#endif
/* LIBC_SCCS and not lint */
269
270
#if HAVE_NBTOOL_CONFIG_H
271
#define GETTEMP __nbcompat_gettemp
272
#else
273
#include <assert.h>
274
#include <errno.h>
275
#include <stdio.h>
276
#include <stdlib.h>
277
#include <
unistd.h
>
278
#include "reentrant.h"
279
#include "local.h"
280
#define GETTEMP __gettemp
281
#endif
282
283
#endif
284
285
char
*
286
mkdtemp
(
char
*path)
287
{
288
_DIAGASSERT
(path !=
NULL
);
289
290
return
GETTEMP
(path,
NULL
, 1) ? path :
NULL
;
291
}
292
293
#endif
/* !HAVE_NBTOOL_CONFIG_H || !HAVE_MKDTEMP */
c.h
start
return str start
Definition
hashfn_unstable.h:289
mkdtemp
char * mkdtemp(char *path)
Definition
mkdtemp.c:286
GETTEMP
static int GETTEMP(char *path, int *doopen, int domkdir)
Definition
mkdtemp.c:94
_DIAGASSERT
#define _DIAGASSERT(x)
Definition
mkdtemp.c:21
e
e
Definition
preproc-init.c:82
fb
static int fb(int x)
Definition
preproc-init.c:92
stat
Definition
win32_port.h:255
unistd.h
stat
#define stat
Definition
win32_port.h:74
lstat
#define lstat(path, sb)
Definition
win32_port.h:275
S_ISDIR
#define S_ISDIR(m)
Definition
win32_port.h:315
mkdir
#define mkdir(a, b)
Definition
win32_port.h:80
src
port
mkdtemp.c
Generated on Tue Jan 27 2026 12:13:17 for PostgreSQL Source Code by
1.9.8