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/e1wtnv2-00047s...@gemulon.postgresql.org

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 (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to