From 8f3ec75de4060d86176ad4ac998eeb87a39748c2 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Sat, 28 Mar 2020 13:01:42 +0100 Subject: [PATCH] Enable Unix-domain sockets support on Windows As of Windows 10 version 1803, Unix-domain sockets are supported on Windows. But it's not automatically detected by configure because it looks for struct sockaddr_un and Windows doesn't define that. So we just make our own definition on Windows and override the configure result. Set DEFAULT_PGSOCKET_DIR to empty on Windows so by default no Unix-domain socket is used, because there is no good standard location. In pg_upgrade, we have to do some extra tweaking to preserve the existing behavior of not using Unix-domain sockets on Windows. Adding support would be desirable, but it needs further work, in particular a way to select whether to use Unix-domain sockets from the command-line or with a run-time test. The pg_upgrade test script needs a fix. The previous code passed "localhost" to postgres -k, which only happened to work because Windows used to ignore the -k argument value altogether. We instead need to pass an empty string to get the desired effect. The test suites will continue to not use Unix-domain sockets on Windows. This requires a small tweak in pg_regress.c. The TAP tests don't need to be changed because they decide by the operating system rather than HAVE_UNIX_SOCKETS. Reviewed-by: Andrew Dunstan Discussion: https://www.postgresql.org/message-id/flat/54bde68c-d134-4eb8-5bd3-8af33b72a010@2ndquadrant.com --- config/c-library.m4 | 5 +++-- configure | 5 ++++- src/bin/pg_upgrade/option.c | 4 ++-- src/bin/pg_upgrade/server.c | 2 +- src/bin/pg_upgrade/test.sh | 11 ++++++----- src/include/c.h | 4 ++++ src/include/pg_config.h.in | 6 +++--- src/include/pg_config_manual.h | 15 ++++++++------- src/include/port/win32.h | 11 +++++++++++ src/test/regress/pg_regress.c | 10 +++++++--- src/tools/msvc/Solution.pm | 2 +- 11 files changed, 50 insertions(+), 25 deletions(-) diff --git a/config/c-library.m4 b/config/c-library.m4 index d9a31d7664..163ad5742d 100644 --- a/config/c-library.m4 +++ b/config/c-library.m4 @@ -102,10 +102,11 @@ AC_DEFUN([PGAC_UNION_SEMUN], # PGAC_STRUCT_SOCKADDR_UN # ----------------------- -# If `struct sockaddr_un' exists, define HAVE_UNIX_SOCKETS. +# If `struct sockaddr_un' exists, define HAVE_STRUCT_SOCKADDR_UN. +# If it is missing then one could define it. # (Requires test for !) AC_DEFUN([PGAC_STRUCT_SOCKADDR_UN], -[AC_CHECK_TYPE([struct sockaddr_un], [AC_DEFINE(HAVE_UNIX_SOCKETS, 1, [Define to 1 if you have unix sockets.])], [], +[AC_CHECK_TYPES([struct sockaddr_un], [], [], [#include #ifdef HAVE_SYS_UN_H #include diff --git a/configure b/configure index 899116517c..83abe872aa 100755 --- a/configure +++ b/configure @@ -14096,7 +14096,10 @@ ac_fn_c_check_type "$LINENO" "struct sockaddr_un" "ac_cv_type_struct_sockaddr_un " if test "x$ac_cv_type_struct_sockaddr_un" = xyes; then : -$as_echo "#define HAVE_UNIX_SOCKETS 1" >>confdefs.h +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_SOCKADDR_UN 1 +_ACEOF + fi diff --git a/src/bin/pg_upgrade/option.c b/src/bin/pg_upgrade/option.c index 4ef2036ecd..aca1ee8b48 100644 --- a/src/bin/pg_upgrade/option.c +++ b/src/bin/pg_upgrade/option.c @@ -468,7 +468,7 @@ adjust_data_dir(ClusterInfo *cluster) void get_sock_dir(ClusterInfo *cluster, bool live_check) { -#ifdef HAVE_UNIX_SOCKETS +#if defined(HAVE_UNIX_SOCKETS) && !defined(WIN32) /* * sockdir and port were added to postmaster.pid in PG 9.1. Pre-9.1 cannot @@ -530,7 +530,7 @@ get_sock_dir(ClusterInfo *cluster, bool live_check) * default */ cluster->sockdir = NULL; -#else /* !HAVE_UNIX_SOCKETS */ +#else /* !HAVE_UNIX_SOCKETS || WIN32 */ cluster->sockdir = NULL; #endif } diff --git a/src/bin/pg_upgrade/server.c b/src/bin/pg_upgrade/server.c index f669bb4e8a..7d17280ecb 100644 --- a/src/bin/pg_upgrade/server.c +++ b/src/bin/pg_upgrade/server.c @@ -210,7 +210,7 @@ start_postmaster(ClusterInfo *cluster, bool report_and_exit_on_error) socket_string[0] = '\0'; -#ifdef HAVE_UNIX_SOCKETS +#if defined(HAVE_UNIX_SOCKETS) && !defined(WIN32) /* prevent TCP/IP connections, restrict socket access */ strcat(socket_string, " -c listen_addresses='' -c unix_socket_permissions=0700"); diff --git a/src/bin/pg_upgrade/test.sh b/src/bin/pg_upgrade/test.sh index 6430610d48..10a28d8133 100644 --- a/src/bin/pg_upgrade/test.sh +++ b/src/bin/pg_upgrade/test.sh @@ -39,14 +39,14 @@ testhost=`uname -s | sed 's/^MSYS/MINGW/'` case $testhost in MINGW*) LISTEN_ADDRESSES="localhost" + PG_REGRESS_SOCKET_DIR="" PGHOST=localhost ;; *) 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 + if [ x"$PG_REGRESS_SOCKET_DIR" = x ]; then set +e dir=`(umask 077 && mktemp -d /tmp/pg_upgrade_check-XXXXXX) 2>/dev/null` @@ -59,14 +59,15 @@ case $testhost in fi fi set -e - PGHOST=$dir - trap 'rm -rf "$PGHOST"' 0 + PG_REGRESS_SOCKET_DIR=$dir + trap 'rm -rf "$PG_REGRESS_SOCKET_DIR"' 0 trap 'exit 3' 1 2 13 15 fi + PGHOST=$PG_REGRESS_SOCKET_DIR ;; esac -POSTMASTER_OPTS="-F -c listen_addresses=\"$LISTEN_ADDRESSES\" -k \"$PGHOST\"" +POSTMASTER_OPTS="-F -c listen_addresses=\"$LISTEN_ADDRESSES\" -k \"$PG_REGRESS_SOCKET_DIR\"" export PGHOST # don't rely on $PWD here, as old shells don't set it diff --git a/src/include/c.h b/src/include/c.h index 831c89f473..d72b23afe4 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -1076,6 +1076,10 @@ extern void ExceptionalCondition(const char *conditionName, * ---------------------------------------------------------------- */ +#ifdef HAVE_STRUCT_SOCKADDR_UN +#define HAVE_UNIX_SOCKETS 1 +#endif + /* * Invert the sign of a qsort-style comparison result, ie, exchange negative * and positive integer values, being careful not to get the wrong answer diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 41ad209380..c199cd46d2 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -566,6 +566,9 @@ /* Define to 1 if `__ss_len' is a member of `struct sockaddr_storage'. */ #undef HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN +/* Define to 1 if the system has the type `struct sockaddr_un'. */ +#undef HAVE_STRUCT_SOCKADDR_UN + /* Define to 1 if `tm_zone' is a member of `struct tm'. */ #undef HAVE_STRUCT_TM_TM_ZONE @@ -647,9 +650,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H -/* Define to 1 if you have unix sockets. */ -#undef HAVE_UNIX_SOCKETS - /* Define to 1 if you have the `unsetenv' function. */ #undef HAVE_UNSETENV diff --git a/src/include/pg_config_manual.h b/src/include/pg_config_manual.h index b7410ff51e..32f739706d 100644 --- a/src/include/pg_config_manual.h +++ b/src/include/pg_config_manual.h @@ -135,13 +135,6 @@ #define EXEC_BACKEND #endif -/* - * Disable UNIX sockets for certain operating systems. - */ -#if defined(WIN32) -#undef HAVE_UNIX_SOCKETS -#endif - /* * USE_POSIX_FADVISE controls whether Postgres will attempt to use the * posix_fadvise() kernel call. Usually the automatic configure tests are @@ -202,8 +195,16 @@ * server will not create an AF_UNIX socket unless the run-time configuration * is changed, a client will connect via TCP/IP by default and will only use * an AF_UNIX socket if one is explicitly specified. + * + * This is done by default on Windows because there is no good standard + * location for AF_UNIX sockets and many installations on Windows don't + * support them yet. */ +#ifndef WIN32 #define DEFAULT_PGSOCKET_DIR "/tmp" +#else +#define DEFAULT_PGSOCKET_DIR "" +#endif /* * This is the default event source for Windows event log. diff --git a/src/include/port/win32.h b/src/include/port/win32.h index bb2f7540b3..c280c131c0 100644 --- a/src/include/port/win32.h +++ b/src/include/port/win32.h @@ -56,3 +56,14 @@ #else #define PGDLLEXPORT #endif + +/* + * Windows headers don't define this structure, but you can define it yourself + * to use the functionality. + */ +struct sockaddr_un +{ + unsigned short sun_family; + char sun_path[108]; +}; +#define HAVE_STRUCT_SOCKADDR_UN 1 diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c index f6a5e1b9c7..6bc19b9668 100644 --- a/src/test/regress/pg_regress.c +++ b/src/test/regress/pg_regress.c @@ -292,7 +292,7 @@ stop_postmaster(void) * 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. + * on Windows, pg_regress does not use Unix sockets. */ static void remove_temp(void) @@ -2120,8 +2120,12 @@ regression_main(int argc, char *argv[], init_function ifunc, test_function tfunc atexit(stop_postmaster); -#ifndef HAVE_UNIX_SOCKETS - /* no unix domain sockets available, so change default */ +#if !defined(HAVE_UNIX_SOCKETS) || defined(WIN32) + /* + * No Unix-domain sockets available, so change default. For now, we also + * don't use them on Windows, even if the build supports them. (See + * comment at remove_temp() for a reason.) + */ hostname = "localhost"; #endif diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index 34d1f61dba..545bdcef7b 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -370,6 +370,7 @@ sub GenerateFiles HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN => undef, HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY => undef, HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN => undef, + HAVE_STRUCT_SOCKADDR_UN => undef, HAVE_STRUCT_TM_TM_ZONE => undef, HAVE_SYNC_FILE_RANGE => undef, HAVE_SYMLINK => 1, @@ -397,7 +398,6 @@ sub GenerateFiles HAVE_UINT8 => undef, HAVE_UNION_SEMUN => undef, HAVE_UNISTD_H => 1, - HAVE_UNIX_SOCKETS => undef, HAVE_UNSETENV => undef, HAVE_USELOCALE => undef, HAVE_UUID_BSD => undef,