Here's a better patch.  I check if there is any declaration at all,
which ancient HPUX should fail based on:

command.c:5062:4: warning: implicit declaration of function 'sigwait'

Then I also check that there isn't an incompatible declaration with
the technique from thread_test.c, which Solaris should fail, based on:

command.c:5062:8: error: too many arguments to function 'sigwait'

A well placed -D_POSIX_PTHREAD_SEMANTICS might allow it work on
Solaris, but I'm not sure if it's OK to do that without other
threading options and I don't have access to test.
From 7341706c3ba1f37a4b202becc63537fb1bc61c8b Mon Sep 17 00:00:00 2001
From: Thomas Munro <tmu...@postgresql.org>
Date: Tue, 13 Jul 2021 19:52:55 +1200
Subject: [PATCH 1/2] Portability fixes for sigwait.

Build farm animals running ancient HPUX and Solaris have a non-standard
sigwait() from draft versions of POSIX, so didn't like commit 7c09d279.
Only try to use sigwait() if it's declared by <signal.h> and matches the
expected declaration.

This can probably be improved for Solaris with build flags, by someone
with access to test.

Also fix the error checking.  Modern sigwait() doesn't set errno.

Discussion: https://postgr.es/m/3187588.1626136248%40sss.pgh.pa.us
---
 configure                  | 54 +++++++++++++++++++++++++++++++++++---
 configure.ac               | 16 +++++++++++
 src/bin/psql/command.c     | 13 ++++-----
 src/bin/psql/startup.c     |  4 +--
 src/include/c.h            |  4 +++
 src/include/pg_config.h.in |  7 +++++
 src/tools/msvc/Solution.pm |  2 ++
 7 files changed, 89 insertions(+), 11 deletions(-)

diff --git a/configure b/configure
index 1ea28a0d67..3fdf0e336d 100755
--- a/configure
+++ b/configure
@@ -15861,9 +15861,7 @@ $as_echo "#define HAVE_FSEEKO 1" >>confdefs.h
 fi
 
 
-# posix_fadvise() is a no-op on Solaris, so don't incur function overhead
-# by calling it, 2009-04-02
-# http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libc/port/gen/posix_fadvise.c
+# Make sure there's a declaration for sigwait().
 # The Clang compiler raises a warning for an undeclared identifier that matches
 # a compiler builtin function.  All extant Clang versions are affected, as of
 # Clang 3.6.0.  Test a builtin known to every version.  This problem affects the
@@ -15952,6 +15950,56 @@ case $ac_cv_c_decl_report in
   *) ac_c_decl_warn_flag= ;;
 esac
 
+ac_fn_c_check_decl "$LINENO" "sigwait" "ac_cv_have_decl_sigwait" "#include <signal.h>
+"
+if test "x$ac_cv_have_decl_sigwait" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_SIGWAIT $ac_have_decl
+_ACEOF
+
+# Make sure it's the standard POSIX interface.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for POSIX-conforming sigwait declaration" >&5
+$as_echo_n "checking for POSIX-conforming sigwait declaration... " >&6; }
+if ${pgac_cv_have_posix_sigwait+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <signal.h>
+int sigwait(const sigset_t *set, int *sig);
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  pgac_cv_have_posix_decl_sigwait=yes
+else
+  pgac_cv_have_posix_decl_sigwait=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_have_posix_sigwait" >&5
+$as_echo "$pgac_cv_have_posix_sigwait" >&6; }
+if test x"$pgac_cv_have_posix_decl_sigwait" = xyes ; then
+
+$as_echo "#define HAVE_POSIX_DECL_SIGWAIT 1" >>confdefs.h
+
+fi
+
+# posix_fadvise() is a no-op on Solaris, so don't incur function overhead
+# by calling it, 2009-04-02
+# http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libc/port/gen/posix_fadvise.c
 if test "$PORTNAME" != "solaris"; then :
 
 for ac_func in posix_fadvise
diff --git a/configure.ac b/configure.ac
index 57336e1fb6..8e57a4f4a8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1741,6 +1741,22 @@ PGAC_CHECK_BUILTIN_FUNC([__builtin_popcount], [unsigned int x])
 # in case it finds that _LARGEFILE_SOURCE has to be #define'd for that.
 AC_FUNC_FSEEKO
 
+# Make sure there's a declaration for sigwait().
+AC_CHECK_DECLS(sigwait, [], [], [#include <signal.h>])
+# Make sure it's the standard POSIX interface.
+AC_CACHE_CHECK([for POSIX-conforming sigwait declaration],
+			   [pgac_cv_have_posix_sigwait],
+[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
+#include <signal.h>
+int sigwait(const sigset_t *set, int *sig);
+],
+[])],
+[pgac_cv_have_posix_decl_sigwait=yes],
+[pgac_cv_have_posix_decl_sigwait=no])])
+if test x"$pgac_cv_have_posix_decl_sigwait" = xyes ; then
+AC_DEFINE(HAVE_POSIX_DECL_SIGWAIT, 1, [Define to 1 if you have a POSIX-conforming sigwait declaration.])
+fi
+
 # posix_fadvise() is a no-op on Solaris, so don't incur function overhead
 # by calling it, 2009-04-02
 # http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libc/port/gen/posix_fadvise.c
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index d704c4220c..376620f68f 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -4899,7 +4899,7 @@ do_watch(PQExpBuffer query_buf, double sleep)
 	FILE	   *pagerpipe = NULL;
 	int			title_len;
 	int			res = 0;
-#ifndef WIN32
+#ifdef USE_SIGWAIT
 	sigset_t	sigalrm_sigchld_sigint;
 	sigset_t	sigalrm_sigchld;
 	sigset_t	sigint;
@@ -4913,7 +4913,7 @@ do_watch(PQExpBuffer query_buf, double sleep)
 		return false;
 	}
 
-#ifndef WIN32
+#ifdef USE_SIGWAIT
 	sigemptyset(&sigalrm_sigchld_sigint);
 	sigaddset(&sigalrm_sigchld_sigint, SIGCHLD);
 	sigaddset(&sigalrm_sigchld_sigint, SIGALRM);
@@ -4952,7 +4952,7 @@ do_watch(PQExpBuffer query_buf, double sleep)
 	 * PAGER environment variables, because traditional pagers probably won't
 	 * be very useful for showing a stream of results.
 	 */
-#ifndef WIN32
+#ifdef USE_SIGWAIT
 	pagerprog = getenv("PSQL_WATCH_PAGER");
 #endif
 	if (pagerprog && myopt.topt.pager)
@@ -5023,7 +5023,7 @@ do_watch(PQExpBuffer query_buf, double sleep)
 		if (pagerpipe && ferror(pagerpipe))
 			break;
 
-#ifdef WIN32
+#ifndef USE_SIGWAIT
 
 		/*
 		 * Set up cancellation of 'watch' via SIGINT.  We redo this each time
@@ -5059,7 +5059,8 @@ do_watch(PQExpBuffer query_buf, double sleep)
 		{
 			int			signal_received;
 
-			if (sigwait(&sigalrm_sigchld_sigint, &signal_received) < 0)
+			errno = sigwait(&sigalrm_sigchld_sigint, &signal_received);
+			if (errno != 0)
 			{
 				/* Some other signal arrived? */
 				if (errno == EINTR)
@@ -5091,7 +5092,7 @@ do_watch(PQExpBuffer query_buf, double sleep)
 		restore_sigpipe_trap();
 	}
 
-#ifndef WIN32
+#ifdef USE_SIGWAIT
 	/* Disable the interval timer. */
 	memset(&interval, 0, sizeof(interval));
 	setitimer(ITIMER_REAL, &interval, NULL);
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index 5f36f0d1c6..f0b46a5efc 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -110,7 +110,7 @@ log_locus_callback(const char **filename, uint64 *lineno)
 	}
 }
 
-#ifndef WIN32
+#ifdef USE_SIGWAIT
 static void
 empty_signal_handler(SIGNAL_ARGS)
 {
@@ -309,7 +309,7 @@ main(int argc, char *argv[])
 
 	psql_setup_cancel_handler();
 
-#ifndef WIN32
+#ifdef USE_SIGWAIT
 
 	/*
 	 * do_watch() needs signal handlers installed (otherwise sigwait() will
diff --git a/src/include/c.h b/src/include/c.h
index c8ede08273..c6daba857d 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -1312,6 +1312,10 @@ extern long long strtoll(const char *str, char **endptr, int base);
 extern unsigned long long strtoull(const char *str, char **endptr, int base);
 #endif
 
+#if HAVE_DECL_SIGWAIT && defined(HAVE_POSIX_DECL_SIGWAIT)
+#define USE_SIGWAIT
+#endif
+
 /* no special DLL markers on most ports */
 #ifndef PGDLLIMPORT
 #define PGDLLIMPORT
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index d69d461ff2..15ffdd895a 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -158,6 +158,10 @@
    don't. */
 #undef HAVE_DECL_RTLD_NOW
 
+/* Define to 1 if you have the declaration of `sigwait', and to 0 if you
+   don't. */
+#undef HAVE_DECL_SIGWAIT
+
 /* Define to 1 if you have the declaration of `strlcat', and to 0 if you
    don't. */
 #undef HAVE_DECL_STRLCAT
@@ -414,6 +418,9 @@
 /* Define to 1 if you have the <poll.h> header file. */
 #undef HAVE_POLL_H
 
+/* Define to 1 if you have a POSIX-conforming sigwait declaration. */
+#undef HAVE_POSIX_DECL_SIGWAIT
+
 /* Define to 1 if you have the `posix_fadvise' function. */
 #undef HAVE_POSIX_FADVISE
 
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 294b968dcd..96a67d254a 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -249,6 +249,7 @@ sub GenerateFiles
 		HAVE_DECL_PWRITEV                           => 0,
 		HAVE_DECL_RTLD_GLOBAL                       => 0,
 		HAVE_DECL_RTLD_NOW                          => 0,
+		HAVE_DECL_SIGWAIT                           => 0,
 		HAVE_DECL_STRLCAT                           => undef,
 		HAVE_DECL_STRLCPY                           => undef,
 		HAVE_DECL_STRNLEN                           => 1,
@@ -334,6 +335,7 @@ sub GenerateFiles
 		HAVE_POLL_H                 => undef,
 		HAVE_POSIX_FADVISE          => undef,
 		HAVE_POSIX_FALLOCATE        => undef,
+		HAVE_POSIX_DECL_SIGWAIT     => undef,
 		HAVE_PPC_LWARX_MUTEX_HINT   => undef,
 		HAVE_PPOLL                  => undef,
 		HAVE_PREAD                  => undef,
-- 
2.30.2

Reply via email to