On Sun, Mar 23, 2014 at 07:04:20PM -0400, Noah Misch wrote:
> On Thu, Mar 06, 2014 at 11:52:22PM -0500, Noah Misch wrote:
> > On Thu, Mar 06, 2014 at 12:44:34PM -0500, Tom Lane wrote:
> > > I'm inclined to suggest that we should put the socket under $CWD by
> > > default, but provide some way for the user to override that choice.
> > > If they want to put it in /tmp, it's on their head as to how secure
> > > that is. On most modern platforms it'd be fine.
> >
> > I am skeptical about the value of protecting systems with non-sticky /tmp,
> > but
> > long $CWD isn't of great importance, either. I'm fine with your suggestion.
> > Though the $CWD or one of its parents could be world-writable, that would
> > typically mean an attacker could just replace the test cases directly.
>
> Here's the patch. The temporary data directory makes for a convenient socket
> directory; initdb already gives it mode 0700, and we have existing
> arrangements to purge it when finished. One can override the socket directory
> by defining PG_REGRESS_SOCK_DIR in the environment.
Socket path length limitations thwarted that patch:
http://www.postgresql.org/message-id/flat/[email protected]
Here's an update that places the socket in a temporary subdirectory of /tmp.
The first attached patch adds NetBSD mkdtemp() to libpgport. The second,
principal, patch uses mkdtemp() to implement this design in pg_regress. The
corresponding change to contrib/pg_upgrade/test.sh is based on the "configure"
script's arrangements for its temporary directory.
NetBSD's mkdtemp() has assertions, and I initially mapped its assertion macro
to our Assert(). However, a bug in our MinGW build process causes build
failures if an Assert() call appears in libpgport. I will post about that in
a new thread. The affected assertions were uncompelling, so I dropped them.
--
Noah Misch
EnterpriseDB http://www.enterprisedb.com
diff --git a/configure b/configure
index ed1ff0a..f8232db 100755
--- a/configure
+++ b/configure
@@ -11650,6 +11650,19 @@ esac
fi
+ac_fn_c_check_func "$LINENO" "mkdtemp" "ac_cv_func_mkdtemp"
+if test "x$ac_cv_func_mkdtemp" = xyes; then :
+ $as_echo "#define HAVE_MKDTEMP 1" >>confdefs.h
+
+else
+ case " $LIBOBJS " in
+ *" mkdtemp.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS mkdtemp.$ac_objext"
+ ;;
+esac
+
+fi
+
ac_fn_c_check_func "$LINENO" "random" "ac_cv_func_random"
if test "x$ac_cv_func_random" = xyes; then :
$as_echo "#define HAVE_RANDOM 1" >>confdefs.h
diff --git a/configure.in b/configure.in
index 80df1d7..c95e2cd 100644
--- a/configure.in
+++ b/configure.in
@@ -1357,7 +1357,7 @@ else
AC_CHECK_FUNCS([fpclass fp_class fp_class_d class], [break])
fi
-AC_REPLACE_FUNCS([crypt fls getopt getrusage inet_aton random rint srandom
strerror strlcat strlcpy])
+AC_REPLACE_FUNCS([crypt fls getopt getrusage inet_aton mkdtemp random rint
srandom strerror strlcat strlcpy])
case $host_os in
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 5ff9e41..4fb7288 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -330,6 +330,9 @@
/* Define to 1 if the system has the type `MINIDUMP_TYPE'. */
#undef HAVE_MINIDUMP_TYPE
+/* Define to 1 if you have the `mkdtemp' function. */
+#undef HAVE_MKDTEMP
+
/* Define to 1 if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32
index e6e3c8d..58777ca 100644
--- a/src/include/pg_config.h.win32
+++ b/src/include/pg_config.h.win32
@@ -249,6 +249,9 @@
/* Define to 1 if the system has the type `MINIDUMP_TYPE'. */
#define HAVE_MINIDUMP_TYPE 1
+/* Define to 1 if you have the `mkdtemp' function. */
+/* #undef HAVE_MKDTEMP */
+
/* Define to 1 if you have the <netinet/in.h> header file. */
#define HAVE_NETINET_IN_H 1
diff --git a/src/include/port.h b/src/include/port.h
index c9226f3..3d97481 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -462,6 +462,9 @@ extern int pg_check_dir(const char *dir);
/* port/pgmkdirp.c */
extern int pg_mkdir_p(char *path, int omode);
+/* port/mkdtemp.c */
+extern char *mkdtemp(char *path);
+
/* port/pqsignal.c */
typedef void (*pqsigfunc) (int signo);
extern pqsigfunc pqsignal(int signo, pqsigfunc func);
diff --git a/src/port/mkdtemp.c b/src/port/mkdtemp.c
new file mode 100644
index 0000000..a5e991f
--- /dev/null
+++ b/src/port/mkdtemp.c
@@ -0,0 +1,293 @@
+/*-------------------------------------------------------------------------
+ *
+ * mkdtemp.c
+ * create a mode-0700 temporary directory
+ *
+ * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * src/port/mkdtemp.c
+ *
+ * This code was taken from NetBSD to provide an implementation for platforms
+ * that lack it. (Among compatibly-licensed implementations, the OpenBSD
+ * version better resists denial-of-service attacks. However, it has a
+ * cryptographic dependency.) The NetBSD copyright terms follow.
+ *-------------------------------------------------------------------------
+ */
+
+#include "c.h"
+
+#define _DIAGASSERT(x) do {} while (0)
+
+
+/* $NetBSD: gettemp.c,v 1.17 2014/01/21 19:09:48 seanb Exp $ */
+
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if HAVE_NBTOOL_CONFIG_H
+#include "nbtool_config.h"
+#endif
+
+#if !HAVE_NBTOOL_CONFIG_H || !HAVE_MKSTEMP || !HAVE_MKDTEMP
+
+#ifdef NOT_POSTGRESQL
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)mktemp.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: gettemp.c,v 1.17 2014/01/21 19:09:48 seanb Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifdef NOT_POSTGRESQL
+#if HAVE_NBTOOL_CONFIG_H
+#define GETTEMP __nbcompat_gettemp
+#else
+#include "reentrant.h"
+#include "local.h"
+#define GETTEMP __gettemp
+#endif
+#endif
+
+static int
+GETTEMP(char *path, int *doopen, int domkdir)
+{
+ char *start,
+ *trv;
+ struct stat sbuf;
+ u_int pid;
+
+ /*
+ * To guarantee multiple calls generate unique names even if the file is
+ * not created. 676 different possibilities with 7 or more X's, 26 with
6
+ * or less.
+ */
+ static char xtra[2] = "aa";
+ int xcnt = 0;
+
+ _DIAGASSERT(path != NULL);
+ /* doopen may be NULL */
+
+ pid = getpid();
+
+ /* Move to end of path and count trailing X's. */
+ for (trv = path; *trv; ++trv)
+ if (*trv == 'X')
+ xcnt++;
+ else
+ xcnt = 0;
+
+ /* Use at least one from xtra. Use 2 if more than 6 X's. */
+ if (xcnt > 0)
+ {
+ *--trv = xtra[0];
+ xcnt--;
+ }
+ if (xcnt > 5)
+ {
+ *--trv = xtra[1];
+ xcnt--;
+ }
+
+ /* Set remaining X's to pid digits with 0's to the left. */
+ for (; xcnt > 0; xcnt--)
+ {
+ *--trv = (pid % 10) + '0';
+ pid /= 10;
+ }
+
+ /* update xtra for next call. */
+ if (xtra[0] != 'z')
+ xtra[0]++;
+ else
+ {
+ xtra[0] = 'a';
+ if (xtra[1] != 'z')
+ xtra[1]++;
+ else
+ xtra[1] = 'a';
+ }
+
+ /*
+ * check the target directory; if you have six X's and it doesn't exist
+ * this runs for a *very* long time.
+ */
+ for (start = trv + 1;; --trv)
+ {
+ if (trv <= path)
+ break;
+ if (*trv == '/')
+ {
+ int e;
+
+ *trv = '\0';
+ e = stat(path, &sbuf);
+ *trv = '/';
+ if (e == -1)
+ return doopen == NULL && !domkdir;
+ if (!S_ISDIR(sbuf.st_mode))
+ {
+ errno = ENOTDIR;
+ return doopen == NULL && !domkdir;
+ }
+ break;
+ }
+ }
+
+ for (;;)
+ {
+ if (doopen)
+ {
+ if ((*doopen =
+ open(path, O_CREAT | O_EXCL | O_RDWR, 0600))
>= 0)
+ return 1;
+ if (errno != EEXIST)
+ return 0;
+ }
+ else if (domkdir)
+ {
+ if (mkdir(path, 0700) >= 0)
+ return 1;
+ if (errno != EEXIST)
+ return 0;
+ }
+ else if (lstat(path, &sbuf))
+ return errno == ENOENT ? 1 : 0;
+
+ /* tricky little algorithm for backward compatibility */
+ for (trv = start;;)
+ {
+ if (!*trv)
+ return 0;
+ if (*trv == 'z')
+ *trv++ = 'a';
+ else
+ {
+ if (isdigit((unsigned char) *trv))
+ *trv = 'a';
+ else
+ ++* trv;
+ break;
+ }
+ }
+ }
+ /* NOTREACHED */
+}
+
+#endif /* !HAVE_NBTOOL_CONFIG_H || !HAVE_MKSTEMP ||
+ *
!HAVE_MKDTEMP */
+
+
+/* $NetBSD: mkdtemp.c,v 1.11 2012/03/15 18:22:30 christos Exp $ */
+
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if HAVE_NBTOOL_CONFIG_H
+#include "nbtool_config.h"
+#endif
+
+#if !HAVE_NBTOOL_CONFIG_H || !HAVE_MKDTEMP
+
+#ifdef NOT_POSTGRESQL
+
+#include <sys/cdefs.h>
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)mktemp.c 8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: mkdtemp.c,v 1.11 2012/03/15 18:22:30 christos Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#if HAVE_NBTOOL_CONFIG_H
+#define GETTEMP __nbcompat_gettemp
+#else
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "reentrant.h"
+#include "local.h"
+#define GETTEMP __gettemp
+#endif
+
+#endif
+
+char *
+mkdtemp(char *path)
+{
+ _DIAGASSERT(path != NULL);
+
+ return GETTEMP(path, NULL, 1) ? path : NULL;
+}
+
+#endif /* !HAVE_NBTOOL_CONFIG_H || !HAVE_MKDTEMP */
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index 260f630..7fe01e6 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -69,7 +69,7 @@ sub mkvcbuild
srandom.c getaddrinfo.c gettimeofday.c inet_net_ntop.c kill.c open.c
erand48.c snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c
pgcheckdir.c pg_crc.c pgmkdirp.c pgsleep.c pgstrcasecmp.c pqsignal.c
- qsort.c qsort_arg.c quotes.c system.c
+ mkdtemp.c qsort.c qsort_arg.c quotes.c system.c
sprompt.c tar.c thread.c getopt.c getopt_long.c dirent.c
win32env.c win32error.c win32setlocale.c);
diff --git a/contrib/pg_upgrade/test.sh b/contrib/pg_upgrade/test.sh
index baa7d47..9d31f9a 100644
--- a/contrib/pg_upgrade/test.sh
+++ b/contrib/pg_upgrade/test.sh
@@ -17,15 +17,43 @@ set -e
unset MAKEFLAGS
unset MAKELEVEL
-# Set listen_addresses desirably
+# Establish how the server will listen for connections
testhost=`uname -s`
case $testhost in
- MINGW*) LISTEN_ADDRESSES="localhost" ;;
- *) LISTEN_ADDRESSES="" ;;
+ MINGW*)
+ LISTEN_ADDRESSES="localhost"
+ PGHOST=""; unset PGHOST
+ ;;
+ *)
+ LISTEN_ADDRESSES=""
+ # Select a socket directory. The algorithm is from the
"configure"
+ # script; the outcome mimics pg_regress.c:make_temp_sockdir().
+ PGHOST=$PG_REGRESS_SOCK_DIR
+ if [ "x$PGHOST" = x ]; then
+ {
+ dir=`(umask 077 &&
+ mktemp -d
/tmp/pg_upgrade_check-XXXXXX) 2>/dev/null` &&
+ [ -d "$dir" ]
+ } ||
+ {
+ dir=/tmp/pg_upgrade_check-$$-$RANDOM
+ (umask 077 && mkdir "$dir")
+ } ||
+ {
+ echo "could not create socket temporary
directory in \"/tmp\""
+ exit 1
+ }
+
+ PGHOST=$dir
+ trap 'rm -rf "$PGHOST"' 0
+ trap 'exit 3' 1 2 13 15
+ fi
+ export PGHOST
+ ;;
esac
-POSTMASTER_OPTS="-F -c listen_addresses=$LISTEN_ADDRESSES"
+POSTMASTER_OPTS="-F -c listen_addresses=$LISTEN_ADDRESSES -k \"$PGHOST\""
temp_root=$PWD/tmp_check
@@ -86,7 +114,6 @@ PGSERVICE=""; unset PGSERVICE
PGSSLMODE=""; unset PGSSLMODE
PGREQUIRESSL=""; unset PGREQUIRESSL
PGCONNECT_TIMEOUT=""; unset PGCONNECT_TIMEOUT
-PGHOST=""; unset PGHOST
PGHOSTADDR=""; unset PGHOSTADDR
# Select a non-conflicting port number, similarly to pg_regress.c
diff --git a/doc/src/sgml/regress.sgml b/doc/src/sgml/regress.sgml
index aee049a..13802e8 100644
--- a/doc/src/sgml/regress.sgml
+++ b/doc/src/sgml/regress.sgml
@@ -58,21 +58,14 @@ make check
<warning>
<para>
- This test method starts a temporary server, which is configured to accept
- any connection originating on the local machine. Any local user can gain
- database superuser privileges when connecting to this server, and could
- in principle exploit all privileges of the operating-system user running
- the tests. Therefore, it is not recommended that you use <literal>make
- check</> on machines shared with untrusted users. Instead, run the tests
- after completing the installation, as described in the next section.
- </para>
-
- <para>
- On Unix-like machines, this danger can be avoided if the temporary
- server's socket file is made inaccessible to other users, for example
- by running the tests in a protected chroot. On Windows, the temporary
- server opens a locally-accessible TCP socket, so filesystem protections
- cannot help.
+ On systems lacking Unix-domain sockets, notably Windows, this test method
+ starts a temporary server configured to accept any connection originating
+ on the local machine. Any local user can gain database superuser
+ privileges when connecting to this server, and could in principle exploit
+ all privileges of the operating-system user running the tests. Therefore,
+ it is not recommended that you use <literal>make check</> on an affected
+ system shared with untrusted users. Instead, run the tests after
+ completing the installation, as described in the next section.
</para>
</warning>
diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c
index 803cf90..27c46ab 100644
--- a/src/test/regress/pg_regress.c
+++ b/src/test/regress/pg_regress.c
@@ -30,6 +30,7 @@
#endif
#include "getopt_long.h"
+#include "libpq/pqcomm.h" /* needed for UNIXSOCK_PATH() */
#include "pg_config_paths.h"
/* for resultmap we need a list of pairs of strings */
@@ -109,6 +110,12 @@ static const char *progname;
static char *logfilename;
static FILE *logfile;
static char *difffilename;
+static const char *sockdir;
+#ifdef HAVE_UNIX_SOCKETS
+static const char *temp_sockdir;
+static char sockself[MAXPGPATH];
+static char socklock[MAXPGPATH];
+#endif
static _resultmap *resultmap = NULL;
@@ -307,6 +314,82 @@ stop_postmaster(void)
}
}
+#ifdef HAVE_UNIX_SOCKETS
+/*
+ * Remove the socket temporary directory. pg_regress never waits for a
+ * postmaster exit, so it is indeterminate whether the postmaster has yet to
+ * unlink the socket and lock file. Unlink them here so we can proceed to
+ * remove the directory. Ignore errors; leaking a temporary directory is
+ * unimportant. This can run from a signal handler. The code is not
+ * acceptable in a Windows signal handler (see initdb.c:trapsig()), but
+ * Windows is not a HAVE_UNIX_SOCKETS platform.
+ */
+static void
+remove_temp(void)
+{
+ Assert(temp_sockdir);
+ unlink(sockself);
+ unlink(socklock);
+ rmdir(temp_sockdir);
+}
+
+/*
+ * Signal handler that calls remove_temp() and reraises the signal.
+ */
+static void
+signal_remove_temp(int signum)
+{
+ remove_temp();
+
+ pqsignal(signum, SIG_DFL);
+ raise(signum);
+}
+
+/*
+ * Create a temporary directory suitable for the server's Unix-domain socket.
+ * The directory will have mode 0700 or stricter, so no other OS user can open
+ * our socket to exploit our use of trust authentication. Most systems
+ * constrain the length of socket paths well below _POSIX_PATH_MAX, so we
+ * place the directory under /tmp rather than relative to the possibly-deep
+ * current working directory.
+ *
+ * Compared to using the compiled-in DEFAULT_PGSOCKET_DIR, this also permits
+ * testing to work in builds that relocate it to a directory not writable to
+ * the build/test user.
+ */
+static const char *
+make_temp_sockdir(void)
+{
+ char *template = strdup("/tmp/pg_regress-XXXXXX");
+
+ temp_sockdir = mkdtemp(template);
+ if (temp_sockdir == NULL)
+ {
+ fprintf(stderr, _("%s: could not create directory \"%s\":
%s\n"),
+ progname, template, strerror(errno));
+ exit(2);
+ }
+
+ /* Stage file names for remove_temp(). Unsafe in a signal handler. */
+ UNIXSOCK_PATH(sockself, port, temp_sockdir);
+ snprintf(socklock, sizeof(socklock), "%s.lock", sockself);
+
+ /* Remove the directory during clean exit. */
+ atexit(remove_temp);
+
+ /*
+ * Remove the directory before dying to the usual signals. Omit
SIGQUIT,
+ * preserving it as a quick, untidy exit.
+ */
+ pqsignal(SIGHUP, signal_remove_temp);
+ pqsignal(SIGINT, signal_remove_temp);
+ pqsignal(SIGPIPE, signal_remove_temp);
+ pqsignal(SIGTERM, signal_remove_temp);
+
+ return temp_sockdir;
+}
+#endif /* HAVE_UNIX_SOCKETS */
+
/*
* Check whether string matches pattern
*
@@ -759,8 +842,7 @@ initialize_environment(void)
* the wrong postmaster, or otherwise behave in nondefault
ways. (Note
* we also use psql's -X switch consistently, so that ~/.psqlrc
files
* won't mess things up.) Also, set PGPORT to the temp port,
and set
- * or unset PGHOST depending on whether we are using TCP or Unix
- * sockets.
+ * PGHOST depending on whether we are using TCP or Unix sockets.
*/
unsetenv("PGDATABASE");
unsetenv("PGUSER");
@@ -769,10 +851,20 @@ initialize_environment(void)
unsetenv("PGREQUIRESSL");
unsetenv("PGCONNECT_TIMEOUT");
unsetenv("PGDATA");
+#ifdef HAVE_UNIX_SOCKETS
if (hostname != NULL)
doputenv("PGHOST", hostname);
else
- unsetenv("PGHOST");
+ {
+ sockdir = getenv("PG_REGRESS_SOCK_DIR");
+ if (!sockdir)
+ sockdir = make_temp_sockdir();
+ doputenv("PGHOST", sockdir);
+ }
+#else
+ Assert(hostname != NULL);
+ doputenv("PGHOST", hostname);
+#endif
unsetenv("PGHOSTADDR");
if (port != -1)
{
@@ -2067,7 +2159,9 @@ regression_main(int argc, char *argv[], init_function
ifunc, test_function tfunc
/*
* To reduce chances of interference with parallel
installations, use
* a port number starting in the private range (49152-65535)
- * calculated from the version number.
+ * calculated from the version number. This aids
!HAVE_UNIX_SOCKETS
+ * systems; elsewhere, the use of a private socket directory
already
+ * prevents interference.
*/
port = 0xC000 | (PG_VERSION_NUM & 0x3FFF);
@@ -2240,10 +2334,11 @@ regression_main(int argc, char *argv[], init_function
ifunc, test_function tfunc
*/
header(_("starting postmaster"));
snprintf(buf, sizeof(buf),
- "\"%s/postgres\" -D \"%s/data\" -F%s -c
\"listen_addresses=%s\" > \"%s/log/postmaster.log\" 2>&1",
- bindir, temp_install,
- debug ? " -d 5" : "",
- hostname ? hostname : "",
+ "\"%s/postgres\" -D \"%s/data\" -F%s "
+ "-c \"listen_addresses=%s\" -k \"%s\" "
+ "> \"%s/log/postmaster.log\" 2>&1",
+ bindir, temp_install, debug ? " -d 5" : "",
+ hostname ? hostname : "", sockdir ? sockdir :
"",
outputdir);
postmaster_pid = spawn_process(buf);
if (postmaster_pid == INVALID_PID)
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers