Re: Avoiding SIGPIPE (was Re: OSDL DBT-2 w/ PostgreSQL - Mailing list pgsql-hackers

From Manfred Spraul
Subject Re: Avoiding SIGPIPE (was Re: OSDL DBT-2 w/ PostgreSQL
Date
Msg-id 3FA420F9.5010507@colorfullife.com
Whole thread Raw
In response to Avoiding SIGPIPE (was Re: OSDL DBT-2 w/ PostgreSQL 7.3.4 and 7.4beta5)  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: Avoiding SIGPIPE (was Re: OSDL DBT-2 w/ PostgreSQL 7.3.4 and 7.4beta5)
List pgsql-hackers
Tom Lane wrote:

>A bigger objection is that we couldn't get libssl to use it (AFAIK).
>The flag really needs to be settable on the socket (eg, via fcntl),
>not per-send.
>
It's a per-send flag, it's not possible to force it on with a fcntl :-(

What about an option to skip the sigaction calls for apps that can
handle SIGPIPE? I'm not sure if an option at connect time, or a flag
accessible through a function like PQsetnonblocking() is the better
approach.

Attached is a patch that adds a connstr option, but I don't like it.

--
    Manfred
Index: fe-connect.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/libpq/fe-connect.c,v
retrieving revision 1.260
diff -c -r1.260 fe-connect.c
*** fe-connect.c    5 Sep 2003 02:08:36 -0000    1.260
--- fe-connect.c    1 Nov 2003 21:02:04 -0000
***************
*** 65,70 ****
--- 65,71 ----
  #else
  #define DefaultSSLMode    "disable"
  #endif
+ #define DefaultSIGPIPEMode    "sigaction"


  /* ----------
***************
*** 152,157 ****
--- 153,161 ----
      {"sslmode", "PGSSLMODE", DefaultSSLMode, NULL,
      "SSL-Mode", "", 8},            /* sizeof("disable") == 8 */

+     {"sigpipemode", "PGSIGPIPEMODE", DefaultSIGPIPEMode, NULL,
+     "SIGPIPE-Mode", "", 10},        /* sizeof("sigaction") == 10 */
+
      /* Terminating entry --- MUST BE LAST */
      {NULL, NULL, NULL, NULL,
      NULL, NULL, 0}
***************
*** 369,374 ****
--- 373,380 ----
          conn->sslmode = strdup("require");
      }
  #endif
+     tmp = conninfo_getval(connOptions, "sigpipemode");
+     conn->sigpipemode = tmp ? strdup(tmp) : NULL;

      /*
       * Free the option info - all is in conn now
***************
*** 478,483 ****
--- 484,508 ----
      else
          conn->sslmode = strdup(DefaultSSLMode);

+     /*
+      * validate sigpipemode option
+      */
+     if (conn->sigpipemode)
+     {
+         if (strcmp(conn->sigpipemode, "caller") != 0
+             && strcmp(conn->sigpipemode, "sigaction") != 0)
+         {
+             conn->status = CONNECTION_BAD;
+             printfPQExpBuffer(&conn->errorMessage,
+                          libpq_gettext("unrecognized sigpipemode: \"%s\"\n"),
+                               conn->sigpipemode);
+             return false;
+         }
+     }
+     else
+         conn->sigpipemode = strdup(DefaultSIGPIPEMode);
+
+
      return true;
  }

***************
*** 951,956 ****
--- 976,986 ----
      else if (conn->sslmode[0] == 'a')    /* "allow" */
          conn->wait_ssl_try = true;
  #endif
+     if (conn->sigpipemode[0] == 's') /* sigaction */
+         conn->do_sigaction = true;
+     else
+         conn->do_sigaction = false;
+

      /*
       * Set up to try to connect, with protocol 3.0 as the first attempt.
***************
*** 2033,2038 ****
--- 2063,2070 ----
          free(conn->pgpass);
      if (conn->sslmode)
          free(conn->sslmode);
+     if (conn->sigpipemode)
+         free(conn->sigpipemode);
      /* Note that conn->Pfdebug is not ours to close or free */
      if (conn->notifyList)
          DLFreeList(conn->notifyList);
Index: fe-secure.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/libpq/fe-secure.c,v
retrieving revision 1.30
diff -c -r1.30 fe-secure.c
*** fe-secure.c    5 Sep 2003 02:08:36 -0000    1.30
--- fe-secure.c    1 Nov 2003 21:02:06 -0000
***************
*** 348,354 ****
      ssize_t        n;

  #ifndef WIN32
!     pqsigfunc    oldsighandler = pqsignal(SIGPIPE, SIG_IGN);
  #endif

  #ifdef USE_SSL
--- 348,357 ----
      ssize_t        n;

  #ifndef WIN32
!     pqsigfunc    oldsighandler = NULL;
!
!     if (conn->do_sigaction)
!         oldsighandler = pqsignal(SIGPIPE, SIG_IGN);
  #endif

  #ifdef USE_SSL
***************
*** 408,414 ****
          n = send(conn->sock, ptr, len, 0);

  #ifndef WIN32
!     pqsignal(SIGPIPE, oldsighandler);
  #endif

      return n;
--- 411,418 ----
          n = send(conn->sock, ptr, len, 0);

  #ifndef WIN32
!     if (conn->do_sigaction)
!         pqsignal(SIGPIPE, oldsighandler);
  #endif

      return n;
Index: libpq-int.h
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/interfaces/libpq/libpq-int.h,v
retrieving revision 1.82
diff -c -r1.82 libpq-int.h
*** libpq-int.h    5 Sep 2003 02:08:36 -0000    1.82
--- libpq-int.h    1 Nov 2003 21:02:07 -0000
***************
*** 250,255 ****
--- 250,256 ----
      char       *pguser;            /* Postgres username and password, if any */
      char       *pgpass;
      char       *sslmode;        /* SSL mode (require,prefer,allow,disable) */
+     char       *sigpipemode;    /* SIGPIPE handling (caller, sigaction) */

      /* Optional file to write trace info to */
      FILE       *Pfdebug;
***************
*** 329,334 ****
--- 330,336 ----
      char        peer_dn[256 + 1];        /* peer distinguished name */
      char        peer_cn[SM_USER + 1];    /* peer common name */
  #endif
+     bool        do_sigaction;    /* set SIGPIPE to SIG_IGN around every send() call */

      /* Buffer for current error message */
      PQExpBufferData errorMessage;        /* expansible string */

pgsql-hackers by date:

Previous
From: Tom Lane
Date:
Subject: Avoiding SIGPIPE (was Re: OSDL DBT-2 w/ PostgreSQL 7.3.4 and 7.4beta5)
Next
From: Manfred Spraul
Date:
Subject: Re: OSDL DBT-2 w/ PostgreSQL 7.3.4 and 7.4beta5