8000 Add mkdtemp() to libpgport. · patchsoft/postgres@8b0d1c8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8b0d1c8

Browse files
committed
Add mkdtemp() to libpgport.
This function is pervasive on free software operating systems; import NetBSD's implementation. Back-patch to 8.4, like the commit that will harness it.
1 parent 6adddac commit 8b0d1c8

File tree

7 files changed

+306
-3
lines changed

7 files changed

+306
-3
lines changed

configure

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18658,7 +18658,8 @@ fi
1865818658

1865918659

1866018660

18661-
for ac_func in crypt getopt getrusage inet_aton random rint srandom strdup strerror strlcat strlcpy strtol strtoul
18661+
18662+
for ac_func in crypt getopt getrusage inet_aton mkdtemp random rint srandom strdup strerror strlcat strlcpy strtol strtoul
1866218663
do
1866318664
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
1866418665
{ echo "$as_me:$LINENO: checking for $ac_func" >&5

configure.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1281,7 +1281,7 @@ else
12811281
AC_CHECK_FUNCS([fpclass fp_class fp_class_d class], [break])
12821282
fi
12831283

1284-
AC_REPLACE_FUNCS([crypt getopt getrusage inet_aton random rint srandom strdup strerror strlcat strlcpy strtol strtoul])
1284+
AC_REPLACE_FUNCS([crypt getopt getrusage inet_aton mkdtemp random rint srandom strdup strerror strlcat strlcpy strtol strtoul])
12851285

12861286
case $host_os in
12871287

src/include/pg_config.h.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,9 @@
321321
/* Define to 1 if you have the <memory.h> header file. */
322322
#undef HAVE_MEMORY_H
323323

324+
/* Define to 1 if you have the `mkdtemp' function. */
325+
#undef HAVE_MKDTEMP
326+
324327
/* Define to 1 if you have the <netinet/in.h> header file. */
325328
#undef HAVE_NETINET_IN_H
326329

src/include/pg_config.h.win32

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,9 @@
258258
/* Define to 1 if you have the <memory.h> header file. */
259259
#define HAVE_MEMORY_H 1
260260

261+
/* Define to 1 if you have the `mkdtemp' function. */
262+
/* #undef HAVE_MKDTEMP */
263+
261264
/* Define to 1 if you have the <netinet/in.h> header file. */
262265
#define HAVE_NETINET_IN_H 1
263266

src/include/port.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,4 +446,7 @@ extern void qsort_arg(void *base, size_t nel, size_t elsize,
446446
/* port/chklocale.c */
447447
extern int pg_get_encoding_from_locale(const char *ctype);
448448

449+
/* port/mkdtemp.c */
450+
extern char *mkdtemp(char *path);
451+
449452
#endif /* PG_PORT_H */

src/port/mkdtemp.c

Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* mkdtemp.c
4+
* create a mode-0700 temporary directory
5+
*
6+
* Portions Copyright (c) 1996-2014, 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 */

src/tools/msvc/Mkvcbuild.pm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ sub mkvcbuild
4747

4848
our @pgportfiles = qw(
4949
chklocale.c crypt.c fseeko.c getrusage.c inet_aton.c random.c srandom.c
50-
getaddrinfo.c gettimeofday.c kill.c open.c rand.c
50+
getaddrinfo.c gettimeofday.c kill.c open.c rand.c mkdtemp.c
5151
snprintf.c strlcat.c strlcpy.c dirmod.c exec.c noblock.c path.c pipe.c
5252
pgsleep.c pgstrcasecmp.c qsort.c qsort_arg.c sprompt.c thread.c
5353
getopt.c getopt_long.c dirent.c rint.c win32env.c win32error.c);

0 commit comments

Comments
 (0)
0