Re: pgsql: Add PSQL_WATCH_PAGER for psql's \watch command. - Mailing list pgsql-committers

From Tom Lane
Subject Re: pgsql: Add PSQL_WATCH_PAGER for psql's \watch command.
Date
Msg-id 3278308.1626198027@sss.pgh.pa.us
Whole thread Raw
In response to Re: pgsql: Add PSQL_WATCH_PAGER for psql's \watch command.  (Thomas Munro <thomas.munro@gmail.com>)
Responses Re: pgsql: Add PSQL_WATCH_PAGER for psql's \watch command.  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-committers
Thomas Munro <thomas.munro@gmail.com> writes:
> Here's a better patch.

I didn't like the way you'd done this as two independent tests;
the second one falsely reports success if there isn't actually
any declaration of sigwait.  I see you hacked around that by
checking both results in c.h, but the printed result is still
very misleading.  Plus it's a waste of time to run the second
test at all, if the first one fails.

Here's a revised patch that I've tested (albeit lightly) on
both HPUX and Solaris.  I also got rid of the independent
check in thread_test.c, since that's always been a hack
that delivers a misleading complaint when it fails.

Personally, I'd skip adding the stanza in c.h in favor of just
making configure set USE_SIGWAIT directly, but perhaps you
see it differently.

            regards, tom lane

diff --git a/config/thread_test.c b/config/thread_test.c
index 784f4fe8ce..e2a9e62f49 100644
--- a/config/thread_test.c
+++ b/config/thread_test.c
@@ -43,10 +43,6 @@
 #include <winsock2.h>
 #endif

-/* Test for POSIX.1c 2-arg sigwait() and fail on single-arg version */
-#include <signal.h>
-int            sigwait(const sigset_t *set, int *sig);
-

 #define        TEMP_FILENAME_1 "thread_test.1"
 #define        TEMP_FILENAME_2 "thread_test.2"
diff --git a/configure b/configure
index 1ea28a0d67..111751defa 100755
--- a/configure
+++ b/configure
@@ -15861,9 +15861,10 @@ $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,
+# PTHREAD_CFLAGS affects the result.
 # 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 +15953,69 @@ 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
+
+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
+  _CFLAGS="$CFLAGS"
+     _LIBS="$LIBS"
+     CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+     LIBS="$LIBS $PTHREAD_LIBS"
+     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
+     CFLAGS="$_CFLAGS"
+     LIBS="$_LIBS"
+
+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
diff --git a/configure.ac b/configure.ac
index 57336e1fb6..1b0e32681a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1741,6 +1741,39 @@ 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,
+# PTHREAD_CFLAGS affects the result.
+AC_CHECK_DECLS(sigwait, [], [], [#include <signal.h>])
+if test "x$ac_cv_have_decl_sigwait" = xyes; then
+  AC_CACHE_CHECK([for POSIX-conforming sigwait declaration],
+    [pgac_cv_have_posix_decl_sigwait],
+    [_CFLAGS="$CFLAGS"
+     _LIBS="$LIBS"
+     CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+     LIBS="$LIBS $PTHREAD_LIBS"
+     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])
+     CFLAGS="$_CFLAGS"
+     LIBS="$_LIBS"
+  ])
+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
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..4feae5ef57 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 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..c967743467 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,
@@ -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,

pgsql-committers by date:

Previous
From: Thomas Munro
Date:
Subject: Re: pgsql: Add PSQL_WATCH_PAGER for psql's \watch command.
Next
From: Tom Lane
Date:
Subject: Re: pgsql: Add PSQL_WATCH_PAGER for psql's \watch command.