Tom Lane wrote:

It strikes me that sigpipe handling will be a global affair in any
particular application --- it's unlikely that it would be correct for
some PG connections and wrong for others. So one possibility is to make
the control variable be global (static) and thus it could be set before
creating the first PGconn.


What about the attached patches?
I hope I found all places that must be updated when a new function is added to libpq.


--
   Manfred
Index: doc/src/sgml/libpq.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql-server/doc/src/sgml/libpq.sgml,v
retrieving revision 1.141
diff -c -r1.141 libpq.sgml
*** doc/src/sgml/libpq.sgml     1 Nov 2003 01:56:29 -0000       1.141
--- doc/src/sgml/libpq.sgml     3 Nov 2003 20:35:57 -0000
***************
*** 645,650 ****
--- 645,693 ----
    </listitem>
   </varlistentry>
  
+  <varlistentry>
+   
<term><function>PQsetsighandling</function><indexterm><primary>PQsetsighandling</></></term>
+   
<term><function>PQgetsighandling</function><indexterm><primary>PQgetsighandling</></></term>
+   <listitem>
+    <para>
+    Set/query SIGPIPE signal handling.
+ <synopsis>
+ void PQsetsighandling(int internal_sigign);
+ </synopsis>
+ <synopsis>
+ int PQgetsighandling(void);
+ </synopsis>
+ </para>
+ 
+ <para>
+     These functions allow to query and set the SIGPIPE signal handling
+     of libpq: by default, Unix systems generate a (fatal) SIGPIPE signal
+     on a send to a socket that lost it's connection. Most callers expect
+     a normal error return instead of the signal. A normal error return
+     can be achieved by blocking or ignoring the SIGPIPE signal. This can
+     be done either globally in the application or inside libpq.
+    </para>
+    <para>
+     If internal signal handling is enabled (this is the default), then
+     libpq sets the SIGPIPE handler to SIG_IGN before every socket send
+     operation and restores it afterwards. This prevents libpq from
+     killing the application, at the cost of a slight performance
+     decrease. This approach is not reliable for multithreaded applications.
+    </para>
+    <para>
+     If internal signal handling is disabled, then the caller is
+     responsible for blocking or handling SIGPIPE signals. This is
+     recommended for multithreaded applications.
+    </para>
+    <para>
+     The signal handler setting is a global flag, it affects all
+     connections. The setting has no effect for Win32 clients - Win32
+     doesn't generate SIGPIPE events.
+    </para>
+   </listitem>
+  </varlistentry>
+ 
+ 
   </variablelist>
  </para>
  </sect1>
Index: src/interfaces/libpq/blibpqdll.def
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/libpq/blibpqdll.def,v
retrieving revision 1.9
diff -c -r1.9 blibpqdll.def
*** src/interfaces/libpq/blibpqdll.def  13 Aug 2003 16:29:03 -0000      1.9
--- src/interfaces/libpq/blibpqdll.def  3 Nov 2003 20:35:59 -0000
***************
*** 113,118 ****
--- 113,120 ----
      _PQfformat               @ 109
      _PQexecPrepared          @ 110
      _PQsendQueryPrepared     @ 111
+     _PQsetsighandling        @ 112
+     _PQgetsighandling        @ 113
  
  ; Aliases for MS compatible names
      PQconnectdb             = _PQconnectdb            
***************
*** 226,228 ****
--- 228,232 ----
      PQfformat               = _PQfformat
      PQexecPrepared          = _PQexecPrepared
      PQsendQueryPrepared     = _PQsendQueryPrepared
+     PQsetsighandling        = _PQsetsighandling
+     PQgetsighandling        = _PQgetsighandling
Index: src/interfaces/libpq/fe-secure.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/libpq/fe-secure.c,v
retrieving revision 1.32
diff -c -r1.32 fe-secure.c
*** src/interfaces/libpq/fe-secure.c    29 Sep 2003 16:38:04 -0000      1.32
--- src/interfaces/libpq/fe-secure.c    3 Nov 2003 20:35:59 -0000
***************
*** 198,203 ****
--- 198,204 ----
  -----END DH PARAMETERS-----\n";
  #endif
  
+ static int do_sigaction = 1;
  /* ------------------------------------------------------------ */
  /*                     Procedures common to all secure sessions                      
 */
  /* ------------------------------------------------------------ */
***************
*** 348,354 ****
        ssize_t         n;
  
  #ifndef WIN32
!       pqsigfunc       oldsighandler = pqsignal(SIGPIPE, SIG_IGN);
  #endif
  
  #ifdef USE_SSL
--- 349,358 ----
        ssize_t         n;
  
  #ifndef WIN32
!       pqsigfunc       oldsighandler = NULL;
! 
!       if (do_sigaction)
!               oldsighandler = pqsignal(SIGPIPE, SIG_IGN);
  #endif
  
  #ifdef USE_SSL
***************
*** 408,417 ****
                n = send(conn->sock, ptr, len, 0);
  
  #ifndef WIN32
!       pqsignal(SIGPIPE, oldsighandler);
  #endif
  
        return n;
  }
  
  /* ------------------------------------------------------------ */
--- 412,432 ----
                n = send(conn->sock, ptr, len, 0);
  
  #ifndef WIN32
!       if (do_sigaction)
!               pqsignal(SIGPIPE, oldsighandler);
  #endif
  
        return n;
+ }
+ 
+ void PQsetsighandling(int internal_sigign)
+ {
+       do_sigaction = internal_sigign;
+ }
+ 
+ int PQgetsighandling(void)
+ {
+       return do_sigaction;
  }
  
  /* ------------------------------------------------------------ */
Index: src/interfaces/libpq/libpq-fe.h
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/libpq/libpq-fe.h,v
retrieving revision 1.100
diff -c -r1.100 libpq-fe.h
*** src/interfaces/libpq/libpq-fe.h     27 Aug 2003 00:33:34 -0000      1.100
--- src/interfaces/libpq/libpq-fe.h     3 Nov 2003 20:36:00 -0000
***************
*** 221,226 ****
--- 221,232 ----
  /* free the data structure returned by PQconndefaults() */
  extern void PQconninfoFree(PQconninfoOption *connOptions);
  
+ /* ===        in fe-secure.c === */
+ 
+ /* get/set SIGPIPE handling */
+ extern void PQsetsighandling(int internal_sigign);
+ extern int PQgetsighandling(void);
+ 
  /*
   * close the current connection and restablish a new one with the same
   * parameters
? contrib/pgbench/pgbench
Index: contrib/pgbench/README.pgbench
===================================================================
RCS file: /projects/cvsroot/pgsql-server/contrib/pgbench/README.pgbench,v
retrieving revision 1.9
diff -c -r1.9 README.pgbench
*** contrib/pgbench/README.pgbench      10 Jun 2003 09:07:15 -0000      1.9
--- contrib/pgbench/README.pgbench      3 Nov 2003 19:53:13 -0000
***************
*** 112,117 ****
--- 112,121 ----
                might be a security hole since ps command will
                show the password. Use this for TESTING PURPOSE ONLY.
  
+       -a
+               Disable SIGPIPE delivery globally instead of within each
+               libpq operation.
+ 
        -n
                No vacuuming and cleaning the history table prior to the
                test is performed.
Index: contrib/pgbench/pgbench.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/contrib/pgbench/pgbench.c,v
retrieving revision 1.27
diff -c -r1.27 pgbench.c
*** contrib/pgbench/pgbench.c   27 Sep 2003 19:15:34 -0000      1.27
--- contrib/pgbench/pgbench.c   3 Nov 2003 19:53:15 -0000
***************
*** 28,33 ****
--- 28,34 ----
  #else
  #include <sys/time.h>
  #include <unistd.h>
+ #include <signal.h>
  
  #ifdef HAVE_GETOPT_H
  #include <getopt.h>
***************
*** 105,112 ****
  static void
  usage()
  {
!       fprintf(stderr, "usage: pgbench [-h hostname][-p port][-c nclients][-t 
ntransactions][-s scaling_factor][-n][-C][-v][-S][-N][-l][-U login][-P 
password][-d][dbname]\n");
!       fprintf(stderr, "(initialize mode): pgbench -i [-h hostname][-p port][-s 
scaling_factor][-U login][-P password][-d][dbname]\n");
  }
  
  /* random number generator */
--- 106,113 ----
  static void
  usage()
  {
!       fprintf(stderr, "usage: pgbench [-h hostname][-p port][-c nclients][-t 
ntransactions][-s scaling_factor][-n][-C][-v][-S][-N][-l][-a][-U login][-P 
password][-d][dbname]\n");
!       fprintf(stderr, "(initialize mode): pgbench -i [-h hostname][-p port][-s 
scaling_factor][-U login][-P password][-d][dbname][-a]\n");
  }
  
  /* random number generator */
***************
*** 703,712 ****
        else if ((env = getenv("PGUSER")) != NULL && *env != '\0')
                login = env;
  
!       while ((c = getopt(argc, argv, "ih:nvp:dc:t:s:U:P:CNSl")) != -1)
        {
                switch (c)
                {
                        case 'i':
                                is_init_mode++;
                                break;
--- 704,719 ----
        else if ((env = getenv("PGUSER")) != NULL && *env != '\0')
                login = env;
  
!       while ((c = getopt(argc, argv, "aih:nvp:dc:t:s:U:P:CNSl")) != -1)
        {
                switch (c)
                {
+                       case 'a':
+ #ifndef WIN32
+                               signal(SIGPIPE, SIG_IGN);
+ #endif
+                               PQsetsighandling(0);
+                               break;
                        case 'i':
                                is_init_mode++;
                                break;
---------------------------(end of broadcast)---------------------------
TIP 8: explain analyze is your friend

Reply via email to