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 */
---------------------------(end of broadcast)---------------------------
TIP 4: Don't 'kill -9' the postmaster

Reply via email to