Re: SIGPIPE handling - Mailing list pgsql-patches
From | Manfred Spraul |
---|---|
Subject | Re: SIGPIPE handling |
Date | |
Msg-id | 3FB7BFDE.3070303@colorfullife.com Whole thread Raw |
In response to | Re: SIGPIPE handling (Bruce Momjian <pgman@candle.pha.pa.us>) |
Responses |
Re: SIGPIPE handling
Re: SIGPIPE handling |
List | pgsql-patches |
Bruce Momjian wrote: >I thought it should be global too, basically testing on the first >connection request. > What if two PQconnect calls happen at the same time? I would really prefer the manual approach with a new PQsetsighandler function - the autodetection is fragile, it's trivial to find a special case where it breaks. Bruce, you wrote that a new function would be overdesign. Are you sure? Your simpler proposals all fail with multithreaded apps. I've attached the patch that implements the global flag with two special function that access it. -- Manfred 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 8 Nov 2003 21:43:53 -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 8 Nov 2003 21:43:54 -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][-Ulogin][-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][-Ulogin][-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; 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 8 Nov 2003 21:43:56 -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 write attempts to a disconnected socket. 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 8 Nov 2003 21:43:57 -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 8 Nov 2003 21:43:58 -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 8 Nov 2003 21:43:58 -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
pgsql-patches by date: