It's a per-send flag, it's not possible to force it on with a fcntl :-(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.
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
