|
11 | 11 | *
|
12 | 12 | *
|
13 | 13 | * IDENTIFICATION
|
14 |
| - * $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.34 2003/12/18 22:49:26 tgl Exp $ |
| 14 | + * $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.35 2004/01/09 02:02:43 momjian Exp $ |
15 | 15 | *
|
16 | 16 | * NOTES
|
17 | 17 | * The client *requires* a valid server certificate. Since
|
|
106 | 106 | #include<arpa/inet.h>
|
107 | 107 | #endif
|
108 | 108 |
|
| 109 | +#ifdefENABLE_THREAD_SAFETY |
| 110 | +#include<pthread.h> |
| 111 | +#endif |
| 112 | + |
109 | 113 | #ifndefHAVE_STRDUP
|
110 | 114 | #include"strdup.h"
|
111 | 115 | #endif
|
@@ -142,6 +146,11 @@ static const char *SSLerrmessage(void);
|
142 | 146 | staticSSL_CTX*SSL_context=NULL;
|
143 | 147 | #endif
|
144 | 148 |
|
| 149 | +#ifdefENABLE_THREAD_SAFETY |
| 150 | +staticvoidsigpipe_handler_ignore_send(intsigno); |
| 151 | +pthread_key_tthread_in_send; |
| 152 | +#endif |
| 153 | + |
145 | 154 | /* ------------------------------------------------------------ */
|
146 | 155 | /* Hardcoded values*/
|
147 | 156 | /* ------------------------------------------------------------ */
|
@@ -347,9 +356,13 @@ pqsecure_write(PGconn *conn, const void *ptr, size_t len)
|
347 | 356 | {
|
348 | 357 | ssize_tn;
|
349 | 358 |
|
| 359 | +#ifdefENABLE_THREAD_SAFETY |
| 360 | +pthread_setspecific(thread_in_send,"t"); |
| 361 | +#else |
350 | 362 | #ifndefWIN32
|
351 | 363 | pqsigfuncoldsighandler=pqsignal(SIGPIPE,SIG_IGN);
|
352 | 364 | #endif
|
| 365 | +#endif |
353 | 366 |
|
354 | 367 | #ifdefUSE_SSL
|
355 | 368 | if (conn->ssl)
|
@@ -407,8 +420,12 @@ pqsecure_write(PGconn *conn, const void *ptr, size_t len)
|
407 | 420 | #endif
|
408 | 421 | n=send(conn->sock,ptr,len,0);
|
409 | 422 |
|
| 423 | +#ifdefENABLE_THREAD_SAFETY |
| 424 | +pthread_setspecific(thread_in_send,"f"); |
| 425 | +#else |
410 | 426 | #ifndefWIN32
|
411 | 427 | pqsignal(SIGPIPE,oldsighandler);
|
| 428 | +#endif |
412 | 429 | #endif
|
413 | 430 |
|
414 | 431 | returnn;
|
@@ -1048,3 +1065,59 @@ PQgetssl(PGconn *conn)
|
1048 | 1065 | }
|
1049 | 1066 |
|
1050 | 1067 | #endif/* USE_SSL */
|
| 1068 | + |
| 1069 | + |
| 1070 | +#ifdefENABLE_THREAD_SAFETY |
| 1071 | +/* |
| 1072 | + *Check SIGPIPE handler and perhaps install our own. |
| 1073 | + */ |
| 1074 | +void |
| 1075 | +check_sigpipe_handler(void) |
| 1076 | +{ |
| 1077 | +pqsigfuncpipehandler; |
| 1078 | + |
| 1079 | +/* |
| 1080 | + *If the app hasn't set a SIGPIPE handler, define our own |
| 1081 | + *that ignores SIGPIPE on libpq send() and does SIG_DFL |
| 1082 | + *for other SIGPIPE cases. |
| 1083 | + */ |
| 1084 | +pipehandler=pqsignalinquire(SIGPIPE); |
| 1085 | +if (pipehandler==SIG_DFL)/* not set by application */ |
| 1086 | +{ |
| 1087 | +/* |
| 1088 | + *Create key first because the signal handler might be called |
| 1089 | + *right after being installed. |
| 1090 | + */ |
| 1091 | +pthread_key_create(&thread_in_send,NULL); |
| 1092 | +pqsignal(SIGPIPE,sigpipe_handler_ignore_send); |
| 1093 | +} |
| 1094 | +} |
| 1095 | + |
| 1096 | +/* |
| 1097 | + *Threaded SIGPIPE signal handler |
| 1098 | + */ |
| 1099 | +void |
| 1100 | +sigpipe_handler_ignore_send(intsigno) |
| 1101 | +{ |
| 1102 | +/* If we have gotten a SIGPIPE outside send(), exit */ |
| 1103 | +if (!PQinSend()) |
| 1104 | +exit(128+SIGPIPE);/* typical return value for SIG_DFL */ |
| 1105 | +} |
| 1106 | +#endif |
| 1107 | + |
| 1108 | +/* |
| 1109 | + *Indicates whether the current thread is in send() |
| 1110 | + *For use by SIGPIPE signal handlers; they should |
| 1111 | + *ignore SIGPIPE when libpq is in send(). This means |
| 1112 | + *that the backend has died unexpectedly. |
| 1113 | + */ |
| 1114 | +pqbool |
| 1115 | +PQinSend(void) |
| 1116 | +{ |
| 1117 | +#ifdefENABLE_THREAD_SAFETY |
| 1118 | +return (pthread_getspecific(thread_in_send)/* has it been set? */&& |
| 1119 | +*(char*)pthread_getspecific(thread_in_send)=='t') ? true : false; |
| 1120 | +#else |
| 1121 | +return false;/* No threading, so we can't be in send() */ |
| 1122 | +#endif |
| 1123 | +} |