Portability fixes for sigwait.
authorThomas Munro
Thu, 15 Jul 2021 00:23:47 +0000 (12:23 +1200)
committerThomas Munro
Thu, 15 Jul 2021 00:34:31 +0000 (12:34 +1200)
Build farm animals running ancient HPUX and Solaris have a non-standard
sigwait() from draft versions of POSIX, so they didn't like commit
7c09d279.  To avoid the problem in general, only try to use sigwait() if
it's declared by  and matches the expected declaration.  To
select the modern declaration on Solaris (even in non-threaded
programs), move -D_POSIX_PTHREAD_SEMANTICS into the right place to
affect all translation units.

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

Thanks to Tom Lane for help with this.

Discussion: https://postgr.es/m/3187588.1626136248%40sss.pgh.pa.us

config/thread_test.c
configure
configure.ac
src/bin/psql/command.c
src/bin/psql/startup.c
src/include/pg_config.h.in
src/tools/msvc/Solution.pm

index 784f4fe8ce3cc3825947a5ae31b5e128af57f453..e2a9e62f49bde2f49af109b7503b2df03188c2e8 100644 (file)
 #include 
 #endif
 
-/* Test for POSIX.1c 2-arg sigwait() and fail on single-arg version */
-#include 
-int            sigwait(const sigset_t *set, int *sig);
-
 
 #define        TEMP_FILENAME_1 "thread_test.1"
 #define        TEMP_FILENAME_2 "thread_test.2"
index 1ea28a0d67d0063bf058782e629fab9281b1c1e7..c85eb1bf55bfe71370df6a4185d4aed30239079f 100755 (executable)
--- a/configure
+++ b/configure
@@ -7194,6 +7194,12 @@ $as_echo "#define PROFILE_PID_DIR 1" >>confdefs.h
   fi
 fi
 
+# On Solaris, we need this #define to get POSIX-conforming versions
+# of many interfaces (sigwait, getpwuid_r, ...).
+if test "$PORTNAME" = "solaris"; then
+  CPPFLAGS="$CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS"
+fi
+
 # We already have this in Makefile.win32, but configure needs it too
 if test "$PORTNAME" = "win32"; then
   CPPFLAGS="$CPPFLAGS -I$srcdir/src/include/port/win32"
@@ -11296,9 +11302,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
    # set thread flags
 
 # Some platforms use these, so just define them.  They can't hurt if they
-# are not supported.  For example, on Solaris -D_POSIX_PTHREAD_SEMANTICS
-# enables 5-arg getpwuid_r, among other things.
-PTHREAD_CFLAGS="$PTHREAD_CFLAGS -D_REENTRANT -D_THREAD_SAFE -D_POSIX_PTHREAD_SEMANTICS"
+# are not supported.
+PTHREAD_CFLAGS="$PTHREAD_CFLAGS -D_REENTRANT -D_THREAD_SAFE"
 
 # Check for *_r functions
 _CFLAGS="$CFLAGS"
@@ -15861,9 +15866,11 @@ $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(), then make sure
+# that it conforms to the POSIX standard (there seem to still be
+# some platforms out there with pre-POSIX sigwait()).  On Solaris,
+# _POSIX_PTHREAD_SEMANTICS affects the result, but we already
+# added that to CPPFLAGS.
 # 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 +15959,62 @@ 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 
+"
+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
+
+if test "x$ac_cv_have_decl_sigwait" = xyes; then
+  { $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_decl_sigwait+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+      #include 
+      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_decl_sigwait" >&5
+$as_echo "$pgac_cv_have_posix_decl_sigwait" >&6; }
+fi
+if test "x$pgac_cv_have_posix_decl_sigwait" = xyes; then
+
+$as_echo "#define HAVE_POSIX_DECL_SIGWAIT 1" >>confdefs.h
+
+else
+  # On non-Windows, libpq requires POSIX sigwait() for thread safety.
+  if test "$enable_thread_safety" = yes -a "$PORTNAME" != "win32"; then
+    as_fn_error $? "POSIX-conforming sigwait is required to enable thread safety." "$LINENO" 5
+  fi
+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
index 57336e1fb6ea6a15738e566983a3181b728df496..099c4a5a45d37aafa18654584796dfcf07ba7480 100644 (file)
@@ -610,6 +610,12 @@ if test "$enable_profiling" = yes && test "$ac_cv_prog_cc_g" = yes; then
   fi
 fi
 
+# On Solaris, we need this #define to get POSIX-conforming versions
+# of many interfaces (sigwait, getpwuid_r, ...).
+if test "$PORTNAME" = "solaris"; then
+  CPPFLAGS="$CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS"
+fi
+
 # We already have this in Makefile.win32, but configure needs it too
 if test "$PORTNAME" = "win32"; then
   CPPFLAGS="$CPPFLAGS -I$srcdir/src/include/port/win32"
@@ -1122,9 +1128,8 @@ AS_IF([test "$enable_thread_safety" = yes -a "$PORTNAME" != "win32"],
 AX_PTHREAD # set thread flags
 
 # Some platforms use these, so just define them.  They can't hurt if they
-# are not supported.  For example, on Solaris -D_POSIX_PTHREAD_SEMANTICS
-# enables 5-arg getpwuid_r, among other things.
-PTHREAD_CFLAGS="$PTHREAD_CFLAGS -D_REENTRANT -D_THREAD_SAFE -D_POSIX_PTHREAD_SEMANTICS"
+# are not supported.
+PTHREAD_CFLAGS="$PTHREAD_CFLAGS -D_REENTRANT -D_THREAD_SAFE"
 
 # Check for *_r functions
 _CFLAGS="$CFLAGS"
@@ -1741,6 +1746,33 @@ 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(), then make sure
+# that it conforms to the POSIX standard (there seem to still be
+# some platforms out there with pre-POSIX sigwait()).  On Solaris,
+# _POSIX_PTHREAD_SEMANTICS affects the result, but we already
+# added that to CPPFLAGS.
+AC_CHECK_DECLS(sigwait, [], [], [#include ])
+if test "x$ac_cv_have_decl_sigwait" = xyes; then
+  AC_CACHE_CHECK([for POSIX-conforming sigwait declaration],
+    [pgac_cv_have_posix_decl_sigwait],
+    [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
+      #include 
+      int sigwait(const sigset_t *set, int *sig);
+      ],
+      [])],
+      [pgac_cv_have_posix_decl_sigwait=yes],
+      [pgac_cv_have_posix_decl_sigwait=no])])
+fi
+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.])
+else
+  # On non-Windows, libpq requires POSIX sigwait() for thread safety.
+  if test "$enable_thread_safety" = yes -a "$PORTNAME" != "win32"; then
+    AC_MSG_ERROR([POSIX-conforming sigwait is required to enable thread safety.])
+  fi
+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
index d704c4220c738fc805c4d60cb6ab0b272d20b455..49d4c0e3ce258a6bd789d418180455c9cc3b5aad 100644 (file)
@@ -4899,7 +4899,7 @@ do_watch(PQExpBuffer query_buf, double sleep)
    FILE       *pagerpipe = NULL;
    int         title_len;
    int         res = 0;
-#ifndef WIN32
+#ifdef HAVE_POSIX_DECL_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 HAVE_POSIX_DECL_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 HAVE_POSIX_DECL_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 HAVE_POSIX_DECL_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 HAVE_POSIX_DECL_SIGWAIT
    /* Disable the interval timer. */
    memset(&interval, 0, sizeof(interval));
    setitimer(ITIMER_REAL, &interval, NULL);
index 5f36f0d1c6dcbf894a01a9a2dbd9f045f5e9a497..2931530f3385379623925e7e2a729c9d3dca18e5 100644 (file)
@@ -110,7 +110,7 @@ log_locus_callback(const char **filename, uint64 *lineno)
    }
 }
 
-#ifndef WIN32
+#ifdef HAVE_POSIX_DECL_SIGWAIT
 static void
 empty_signal_handler(SIGNAL_ARGS)
 {
@@ -309,7 +309,7 @@ main(int argc, char *argv[])
 
    psql_setup_cancel_handler();
 
-#ifndef WIN32
+#ifdef HAVE_POSIX_DECL_SIGWAIT
 
    /*
     * do_watch() needs signal handlers installed (otherwise sigwait() will
index d69d461ff2cd2dc792c5c61249c109252273b8b8..15ffdd895aad9314077e937ce6437cac1cdcf698 100644 (file)
    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
 /* Define to 1 if you have the  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
 
index 294b968dcdb5cdf1f097d3a3f80a5f2371c7512b..c967743467b32c4c38b1c3efab5ff74a54c58690 100644 (file)
@@ -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,
@@ -332,6 +333,7 @@ sub GenerateFiles
        HAVE_PAM_PAM_APPL_H         => undef,
        HAVE_POLL                   => undef,
        HAVE_POLL_H                 => undef,
+       HAVE_POSIX_DECL_SIGWAIT     => undef,
        HAVE_POSIX_FADVISE          => undef,
        HAVE_POSIX_FALLOCATE        => undef,
        HAVE_PPC_LWARX_MUTEX_HINT   => undef,