1 /*-------------------------------------------------------------------------
4 * functions related to setting up a secure connection to the backend.
5 * Secure connections are expected to provide confidentiality,
6 * message integrity and endpoint authentication.
9 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
10 * Portions Copyright (c) 1994, Regents of the University of California
14 * $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.109 2008/11/24 19:19:46 mha Exp $
18 * We don't provide informational callbacks here (like
19 * info_cb() in be-secure.c), since there's mechanism to
20 * display that information to the client.
22 *-------------------------------------------------------------------------
25 #include "postgres_fe.h"
38 #include <sys/socket.h>
41 #include <netinet/in.h>
42 #ifdef HAVE_NETINET_TCP_H
43 #include <netinet/tcp.h>
45 #include <arpa/inet.h>
49 #ifdef ENABLE_THREAD_SAFETY
51 #include "pthread-win32.h"
58 #include <openssl/ssl.h>
59 #include <openssl/bio.h>
60 #if (SSLEAY_VERSION_NUMBER >= 0x00907000L)
61 #include <openssl/conf.h>
63 #if (SSLEAY_VERSION_NUMBER >= 0x00907000L) && !defined(OPENSSL_NO_ENGINE)
64 #include <openssl/engine.h>
67 /* fnmatch() needed for client certificate checking */
71 #include "fnmatchstub.h"
79 #define USER_CERT_FILE ".postgresql/postgresql.crt"
80 #define USER_KEY_FILE ".postgresql/postgresql.key"
81 #define ROOT_CERT_FILE ".postgresql/root.crt"
82 #define ROOT_CRL_FILE ".postgresql/root.crl"
84 /* On Windows, the "home" directory is already PostgreSQL-specific */
85 #define USER_CERT_FILE "postgresql.crt"
86 #define USER_KEY_FILE "postgresql.key"
87 #define ROOT_CERT_FILE "root.crt"
88 #define ROOT_CRL_FILE "root.crl"
91 #ifndef HAVE_ERR_SET_MARK
92 /* These don't exist in OpenSSL before 0.9.8 */
93 #define ERR_set_mark() ((void) 0)
94 #define ERR_pop_to_mark() ((void) 0)
97 static bool verify_peer_name_matches_certificate(PGconn *);
98 static int verify_cb(int ok, X509_STORE_CTX *ctx);
99 static int client_cert_cb(SSL *, X509 **, EVP_PKEY **);
100 static int init_ssl_system(PGconn *conn);
101 static int initialize_SSL(PGconn *);
102 static void destroy_SSL(void);
103 static PostgresPollingStatusType open_client_SSL(PGconn *);
104 static void close_SSL(PGconn *);
105 static char *SSLerrmessage(void);
106 static void SSLerrfree(char *buf);
110 static bool pq_initssllib = true;
112 static SSL_CTX *SSL_context = NULL;
116 * Macros to handle disabling and then restoring the state of SIGPIPE handling.
117 * Note that DISABLE_SIGPIPE() must appear at the start of a block.
121 #ifdef ENABLE_THREAD_SAFETY
123 #define DISABLE_SIGPIPE(failaction) \
125 bool sigpipe_pending; \
126 bool got_epipe = false; \
128 if (pq_block_sigpipe(&osigmask, &sigpipe_pending) < 0) \
131 #define REMEMBER_EPIPE(cond) \
137 #define RESTORE_SIGPIPE() \
138 pq_reset_sigpipe(&osigmask, sigpipe_pending, got_epipe)
140 #else /* !ENABLE_THREAD_SAFETY */
142 #define DISABLE_SIGPIPE(failaction) \
143 pqsigfunc oldsighandler = pqsignal(SIGPIPE, SIG_IGN)
145 #define REMEMBER_EPIPE(cond)
147 #define RESTORE_SIGPIPE() \
148 pqsignal(SIGPIPE, oldsighandler)
150 #endif /* ENABLE_THREAD_SAFETY */
153 #define DISABLE_SIGPIPE(failaction)
154 #define REMEMBER_EPIPE(cond)
155 #define RESTORE_SIGPIPE()
159 /* ------------------------------------------------------------ */
160 /* Procedures common to all secure sessions */
161 /* ------------------------------------------------------------ */
165 * Exported function to allow application to tell us it's already
166 * initialized OpenSSL.
169 PQinitSSL(int do_init)
172 pq_initssllib = do_init;
177 * Initialize global context
180 pqsecure_initialize(PGconn *conn)
185 r = initialize_SSL(conn);
192 * Destroy global context
195 pqsecure_destroy(void)
203 * Attempt to negotiate secure session.
205 PostgresPollingStatusType
206 pqsecure_open_client(PGconn *conn)
209 /* First time through? */
210 if (conn->ssl == NULL)
212 if (!(conn->ssl = SSL_new(SSL_context)) ||
213 !SSL_set_app_data(conn->ssl, conn) ||
214 !SSL_set_fd(conn->ssl, conn->sock))
216 char *err = SSLerrmessage();
218 printfPQExpBuffer(&conn->errorMessage,
219 libpq_gettext("could not establish SSL connection: %s\n"),
223 return PGRES_POLLING_FAILED;
227 * Initialize errorMessage to empty. This allows open_client_SSL() to
228 * detect whether client_cert_cb() has stored a message.
230 resetPQExpBuffer(&conn->errorMessage);
232 /* Begin or continue the actual handshake */
233 return open_client_SSL(conn);
235 /* shouldn't get here */
236 return PGRES_POLLING_FAILED;
241 * Close secure session.
244 pqsecure_close(PGconn *conn)
253 * Read data from a secure connection.
256 pqsecure_read(PGconn *conn, void *ptr, size_t len)
265 /* SSL_read can write to the socket, so we need to disable SIGPIPE */
266 DISABLE_SIGPIPE(return -1);
269 n = SSL_read(conn->ssl, ptr, len);
270 err = SSL_get_error(conn->ssl, n);
275 case SSL_ERROR_WANT_READ:
278 case SSL_ERROR_WANT_WRITE:
281 * Returning 0 here would cause caller to wait for read-ready,
282 * which is not correct since what SSL wants is wait for
283 * write-ready. The former could get us stuck in an infinite
284 * wait, so don't risk it; busy-loop instead.
287 case SSL_ERROR_SYSCALL:
293 REMEMBER_EPIPE(SOCK_ERRNO == EPIPE);
294 printfPQExpBuffer(&conn->errorMessage,
295 libpq_gettext("SSL SYSCALL error: %s\n"),
296 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
300 printfPQExpBuffer(&conn->errorMessage,
301 libpq_gettext("SSL SYSCALL error: EOF detected\n"));
303 SOCK_ERRNO_SET(ECONNRESET);
310 char *err = SSLerrmessage();
312 printfPQExpBuffer(&conn->errorMessage,
313 libpq_gettext("SSL error: %s\n"), err);
317 case SSL_ERROR_ZERO_RETURN:
318 SOCK_ERRNO_SET(ECONNRESET);
322 printfPQExpBuffer(&conn->errorMessage,
323 libpq_gettext("unrecognized SSL error code: %d\n"),
333 n = recv(conn->sock, ptr, len, 0);
339 * Write data to a secure connection.
342 pqsecure_write(PGconn *conn, const void *ptr, size_t len)
346 DISABLE_SIGPIPE(return -1);
353 n = SSL_write(conn->ssl, ptr, len);
354 err = SSL_get_error(conn->ssl, n);
359 case SSL_ERROR_WANT_READ:
362 * Returning 0 here causes caller to wait for write-ready,
363 * which is not really the right thing, but it's the best we
368 case SSL_ERROR_WANT_WRITE:
371 case SSL_ERROR_SYSCALL:
377 REMEMBER_EPIPE(SOCK_ERRNO == EPIPE);
378 printfPQExpBuffer(&conn->errorMessage,
379 libpq_gettext("SSL SYSCALL error: %s\n"),
380 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
384 printfPQExpBuffer(&conn->errorMessage,
385 libpq_gettext("SSL SYSCALL error: EOF detected\n"));
386 SOCK_ERRNO_SET(ECONNRESET);
393 char *err = SSLerrmessage();
395 printfPQExpBuffer(&conn->errorMessage,
396 libpq_gettext("SSL error: %s\n"), err);
400 case SSL_ERROR_ZERO_RETURN:
401 SOCK_ERRNO_SET(ECONNRESET);
405 printfPQExpBuffer(&conn->errorMessage,
406 libpq_gettext("unrecognized SSL error code: %d\n"),
415 n = send(conn->sock, ptr, len, 0);
416 REMEMBER_EPIPE(n < 0 && SOCK_ERRNO == EPIPE);
424 /* ------------------------------------------------------------ */
425 /* SSL specific code */
426 /* ------------------------------------------------------------ */
430 * Certificate verification callback
432 * This callback allows us to log intermediate problems during
433 * verification, but there doesn't seem to be a clean way to get
434 * our PGconn * structure. So we can't log anything!
436 * This callback also allows us to override the default acceptance
437 * criteria (e.g., accepting self-signed or expired certs), but
438 * for now we accept the default checks.
441 verify_cb(int ok, X509_STORE_CTX *ctx)
447 * Verify that common name resolves to peer.
450 verify_peer_name_matches_certificate(PGconn *conn)
453 * If told not to verify the peer name, don't do it. Return
454 * 0 indicating that the verification was successful.
456 if(strcmp(conn->sslverify, "cn") != 0)
459 if (conn->pghostaddr)
461 printfPQExpBuffer(&conn->errorMessage,
462 libpq_gettext("verified SSL connections are only supported when connecting to a hostname"));
468 * Connect by hostname.
470 * XXX: Should support alternate names here
472 if (pg_strcasecmp(conn->peer_cn, conn->pghost) == 0)
473 /* Exact name match */
475 else if (fnmatch(conn->peer_cn, conn->pghost, FNM_NOESCAPE/* | FNM_CASEFOLD*/) == 0)
476 /* Matched wildcard certificate */
480 printfPQExpBuffer(&conn->errorMessage,
481 libpq_gettext("server common name '%s' does not match hostname '%s'"),
482 conn->peer_cn, conn->pghost);
489 * Callback used by SSL to load client cert and key.
490 * This callback is only called when the server wants a
493 * Since BIO functions can set OpenSSL error codes, we must
494 * reset the OpenSSL error stack on *every* exit from this
495 * function once we've started using BIO.
497 * Must return 1 on success, 0 on no data or error.
500 client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
502 char homedir[MAXPGPATH];
509 char fnbuf[MAXPGPATH];
511 PGconn *conn = (PGconn *) SSL_get_app_data(ssl);
514 if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
516 printfPQExpBuffer(&conn->errorMessage,
517 libpq_gettext("could not get user information\n"));
521 /* read the user certificate */
522 snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_CERT_FILE);
525 * OpenSSL <= 0.9.8 lacks error stack handling, which means it's likely to
526 * report wrong error messages if access to the cert file fails. Do our
527 * own check for the readability of the file to catch the majority of such
528 * problems before OpenSSL gets involved.
530 #ifndef HAVE_ERR_SET_MARK
534 if ((fp2 = fopen(fnbuf, "r")) == NULL)
536 printfPQExpBuffer(&conn->errorMessage,
537 libpq_gettext("could not open certificate file \"%s\": %s\n"),
538 fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
545 /* save OpenSSL error stack */
548 if ((bio = BIO_new_file(fnbuf, "r")) == NULL)
550 printfPQExpBuffer(&conn->errorMessage,
551 libpq_gettext("could not open certificate file \"%s\": %s\n"),
552 fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
557 if (PEM_read_bio_X509(bio, x509, NULL, NULL) == NULL)
559 char *err = SSLerrmessage();
561 printfPQExpBuffer(&conn->errorMessage,
562 libpq_gettext("could not read certificate file \"%s\": %s\n"),
572 #if (SSLEAY_VERSION_NUMBER >= 0x00907000L) && !defined(OPENSSL_NO_ENGINE)
573 if (getenv("PGSSLKEY"))
575 /* read the user key from engine */
576 char *engine_env = getenv("PGSSLKEY");
577 char *engine_colon = strchr(engine_env, ':');
583 printfPQExpBuffer(&conn->errorMessage,
584 libpq_gettext("invalid value of PGSSLKEY environment variable\n"));
589 engine_str = malloc(engine_colon - engine_env + 1);
590 strlcpy(engine_str, engine_env, engine_colon - engine_env + 1);
591 engine_ptr = ENGINE_by_id(engine_str);
592 if (engine_ptr == NULL)
594 char *err = SSLerrmessage();
596 printfPQExpBuffer(&conn->errorMessage,
597 libpq_gettext("could not load SSL engine \"%s\": %s\n"),
605 *pkey = ENGINE_load_private_key(engine_ptr, engine_colon + 1,
609 char *err = SSLerrmessage();
611 printfPQExpBuffer(&conn->errorMessage,
612 libpq_gettext("could not read private SSL key \"%s\" from engine \"%s\": %s\n"),
613 engine_colon + 1, engine_str, err);
622 #endif /* use PGSSLKEY */
624 /* read the user key from file */
625 snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_KEY_FILE);
626 if (stat(fnbuf, &buf) != 0)
628 printfPQExpBuffer(&conn->errorMessage,
629 libpq_gettext("certificate present, but not private key file \"%s\"\n"),
635 if (!S_ISREG(buf.st_mode) || buf.st_mode & (S_IRWXG | S_IRWXO))
637 printfPQExpBuffer(&conn->errorMessage,
638 libpq_gettext("private key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),
645 if ((bio = BIO_new_file(fnbuf, "r")) == NULL)
647 printfPQExpBuffer(&conn->errorMessage,
648 libpq_gettext("could not open private key file \"%s\": %s\n"),
649 fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
654 BIO_get_fp(bio, &fp);
655 if (fstat(fileno(fp), &buf2) == -1 ||
656 buf.st_dev != buf2.st_dev || buf.st_ino != buf2.st_ino)
658 printfPQExpBuffer(&conn->errorMessage,
659 libpq_gettext("private key file \"%s\" changed during execution\n"), fnbuf);
665 if (PEM_read_bio_PrivateKey(bio, pkey, NULL, NULL) == NULL)
667 char *err = SSLerrmessage();
669 printfPQExpBuffer(&conn->errorMessage,
670 libpq_gettext("could not read private key file \"%s\": %s\n"),
682 /* verify that the cert and key go together */
683 if (!X509_check_private_key(*x509, *pkey))
685 char *err = SSLerrmessage();
687 printfPQExpBuffer(&conn->errorMessage,
688 libpq_gettext("certificate does not match private key file \"%s\": %s\n"),
700 #ifdef ENABLE_THREAD_SAFETY
703 pq_threadidcallback(void)
706 * This is not standards-compliant. pthread_self() returns pthread_t, and
707 * shouldn't be cast to unsigned long, but CRYPTO_set_id_callback requires
708 * it, so we have to do it.
710 return (unsigned long) pthread_self();
713 static pthread_mutex_t *pq_lockarray;
716 pq_lockingcallback(int mode, int n, const char *file, int line)
718 if (mode & CRYPTO_LOCK)
720 if (pthread_mutex_lock(&pq_lockarray[n]))
721 PGTHREAD_ERROR("failed to lock mutex");
725 if (pthread_mutex_unlock(&pq_lockarray[n]))
726 PGTHREAD_ERROR("failed to unlock mutex");
729 #endif /* ENABLE_THREAD_SAFETY */
732 * Also see similar code in fe-connect.c, default_threadlock()
735 init_ssl_system(PGconn *conn)
737 #ifdef ENABLE_THREAD_SAFETY
739 static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
741 static pthread_mutex_t init_mutex = NULL;
742 static long mutex_initlock = 0;
744 if (init_mutex == NULL)
746 while (InterlockedExchange(&mutex_initlock, 1) == 1)
747 /* loop, another thread own the lock */ ;
748 if (init_mutex == NULL)
750 if (pthread_mutex_init(&init_mutex, NULL))
753 InterlockedExchange(&mutex_initlock, 0);
756 if (pthread_mutex_lock(&init_mutex))
759 if (pq_initssllib && pq_lockarray == NULL)
763 CRYPTO_set_id_callback(pq_threadidcallback);
765 pq_lockarray = malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks());
768 pthread_mutex_unlock(&init_mutex);
771 for (i = 0; i < CRYPTO_num_locks(); i++)
773 if (pthread_mutex_init(&pq_lockarray[i], NULL))
777 CRYPTO_set_locking_callback(pq_lockingcallback);
784 #if SSLEAY_VERSION_NUMBER >= 0x00907000L
785 OPENSSL_config(NULL);
788 SSL_load_error_strings();
790 SSL_context = SSL_CTX_new(TLSv1_method());
793 char *err = SSLerrmessage();
795 printfPQExpBuffer(&conn->errorMessage,
796 libpq_gettext("could not create SSL context: %s\n"),
799 #ifdef ENABLE_THREAD_SAFETY
800 pthread_mutex_unlock(&init_mutex);
805 #ifdef ENABLE_THREAD_SAFETY
806 pthread_mutex_unlock(&init_mutex);
812 * Initialize global SSL context.
815 initialize_SSL(PGconn *conn)
818 char homedir[MAXPGPATH];
819 char fnbuf[MAXPGPATH];
821 if (init_ssl_system(conn))
825 * If sslverify is set to anything other than "none", perform certificate
826 * verification. If set to "cn" we will also do further verifications after
827 * the connection has been completed.
830 /* Set up to verify server cert, if root.crt is present */
831 if (pqGetHomeDirectory(homedir, sizeof(homedir)))
833 snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CERT_FILE);
834 if (stat(fnbuf, &buf) == 0)
838 if (!SSL_CTX_load_verify_locations(SSL_context, fnbuf, NULL))
840 char *err = SSLerrmessage();
842 printfPQExpBuffer(&conn->errorMessage,
843 libpq_gettext("could not read root certificate file \"%s\": %s\n"),
849 if ((cvstore = SSL_CTX_get_cert_store(SSL_context)) != NULL)
851 /* setting the flags to check against the complete CRL chain */
852 if (X509_STORE_load_locations(cvstore, ROOT_CRL_FILE, NULL) != 0)
853 /* OpenSSL 0.96 does not support X509_V_FLAG_CRL_CHECK */
854 #ifdef X509_V_FLAG_CRL_CHECK
855 X509_STORE_set_flags(cvstore,
856 X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
857 /* if not found, silently ignore; we do not require CRL */
860 char *err = SSLerrmessage();
862 printfPQExpBuffer(&conn->errorMessage,
863 libpq_gettext("SSL library does not support CRL certificates (file \"%s\")\n"),
871 SSL_CTX_set_verify(SSL_context, SSL_VERIFY_PEER, verify_cb);
875 if (strcmp(conn->sslverify, "none") != 0)
877 printfPQExpBuffer(&conn->errorMessage,
878 libpq_gettext("root certificate file (%s) not found"), fnbuf);
885 if (strcmp(conn->sslverify, "none") != 0)
887 printfPQExpBuffer(&conn->errorMessage,
888 libpq_gettext("cannot find home directory to locate root certificate file"));
893 /* set up mechanism to provide client certificate, if available */
894 SSL_CTX_set_client_cert_cb(SSL_context, client_cert_cb);
900 * Destroy global SSL context.
907 SSL_CTX_free(SSL_context);
913 * Attempt to negotiate SSL connection.
915 static PostgresPollingStatusType
916 open_client_SSL(PGconn *conn)
920 r = SSL_connect(conn->ssl);
923 int err = SSL_get_error(conn->ssl, r);
927 case SSL_ERROR_WANT_READ:
928 return PGRES_POLLING_READING;
930 case SSL_ERROR_WANT_WRITE:
931 return PGRES_POLLING_WRITING;
933 case SSL_ERROR_SYSCALL:
938 printfPQExpBuffer(&conn->errorMessage,
939 libpq_gettext("SSL SYSCALL error: %s\n"),
940 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
942 printfPQExpBuffer(&conn->errorMessage,
943 libpq_gettext("SSL SYSCALL error: EOF detected\n"));
945 return PGRES_POLLING_FAILED;
950 * If there are problems with the local certificate files,
951 * these will be detected by client_cert_cb() which is
952 * called from SSL_connect(). We want to return that
953 * error message and not the rather unhelpful error that
954 * OpenSSL itself returns. So check to see if an error
955 * message was already stored.
957 if (conn->errorMessage.len == 0)
959 char *err = SSLerrmessage();
961 printfPQExpBuffer(&conn->errorMessage,
962 libpq_gettext("SSL error: %s\n"),
967 return PGRES_POLLING_FAILED;
971 printfPQExpBuffer(&conn->errorMessage,
972 libpq_gettext("unrecognized SSL error code: %d\n"),
975 return PGRES_POLLING_FAILED;
980 * We already checked the server certificate in initialize_SSL()
981 * using SSL_CTX_set_verify() if root.crt exists.
984 /* pull out server distinguished and common names */
985 conn->peer = SSL_get_peer_certificate(conn->ssl);
986 if (conn->peer == NULL)
988 char *err = SSLerrmessage();
990 printfPQExpBuffer(&conn->errorMessage,
991 libpq_gettext("certificate could not be obtained: %s\n"),
995 return PGRES_POLLING_FAILED;
998 X509_NAME_oneline(X509_get_subject_name(conn->peer),
999 conn->peer_dn, sizeof(conn->peer_dn));
1000 conn->peer_dn[sizeof(conn->peer_dn) - 1] = '\0';
1002 X509_NAME_get_text_by_NID(X509_get_subject_name(conn->peer),
1003 NID_commonName, conn->peer_cn, SM_USER);
1004 conn->peer_cn[SM_USER] = '\0';
1006 if (!verify_peer_name_matches_certificate(conn))
1009 return PGRES_POLLING_FAILED;
1012 /* SSL handshake is complete */
1013 return PGRES_POLLING_OK;
1017 * Close SSL connection.
1020 close_SSL(PGconn *conn)
1024 DISABLE_SIGPIPE((void) 0);
1025 SSL_shutdown(conn->ssl);
1026 SSL_free(conn->ssl);
1028 /* We have to assume we got EPIPE */
1029 REMEMBER_EPIPE(true);
1035 X509_free(conn->peer);
1041 * Obtain reason string for last SSL error
1043 * Some caution is needed here since ERR_reason_error_string will
1044 * return NULL if it doesn't recognize the error code. We don't
1045 * want to return NULL ever.
1047 static char ssl_nomem[] = "out of memory allocating error description";
1049 #define SSL_ERR_LEN 128
1054 unsigned long errcode;
1055 const char *errreason;
1058 errbuf = malloc(SSL_ERR_LEN);
1061 errcode = ERR_get_error();
1064 snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("no SSL error reported"));
1067 errreason = ERR_reason_error_string(errcode);
1068 if (errreason != NULL)
1070 strlcpy(errbuf, errreason, SSL_ERR_LEN);
1073 snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("SSL error code %lu"), errcode);
1078 SSLerrfree(char *buf)
1080 if (buf != ssl_nomem)
1085 * Return pointer to OpenSSL object.
1088 PQgetssl(PGconn *conn)
1094 #else /* !USE_SSL */
1097 PQgetssl(PGconn *conn)
1101 #endif /* USE_SSL */
1104 #if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
1107 * Block SIGPIPE for this thread. This prevents send()/write() from exiting
1111 pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending)
1113 sigset_t sigpipe_sigset;
1116 sigemptyset(&sigpipe_sigset);
1117 sigaddset(&sigpipe_sigset, SIGPIPE);
1119 /* Block SIGPIPE and save previous mask for later reset */
1120 SOCK_ERRNO_SET(pthread_sigmask(SIG_BLOCK, &sigpipe_sigset, osigset));
1124 /* We can have a pending SIGPIPE only if it was blocked before */
1125 if (sigismember(osigset, SIGPIPE))
1127 /* Is there a pending SIGPIPE? */
1128 if (sigpending(&sigset) != 0)
1131 if (sigismember(&sigset, SIGPIPE))
1132 *sigpipe_pending = true;
1134 *sigpipe_pending = false;
1137 *sigpipe_pending = false;
1143 * Discard any pending SIGPIPE and reset the signal mask.
1145 * Note: we are effectively assuming here that the C library doesn't queue
1146 * up multiple SIGPIPE events. If it did, then we'd accidentally leave
1147 * ours in the queue when an event was already pending and we got another.
1148 * As long as it doesn't queue multiple events, we're OK because the caller
1149 * can't tell the difference.
1151 * The caller should say got_epipe = FALSE if it is certain that it
1152 * didn't get an EPIPE error; in that case we'll skip the clear operation
1153 * and things are definitely OK, queuing or no. If it got one or might have
1154 * gotten one, pass got_epipe = TRUE.
1156 * We do not want this to change errno, since if it did that could lose
1157 * the error code from a preceding send(). We essentially assume that if
1158 * we were able to do pq_block_sigpipe(), this can't fail.
1161 pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe)
1163 int save_errno = SOCK_ERRNO;
1167 /* Clear SIGPIPE only if none was pending */
1168 if (got_epipe && !sigpipe_pending)
1170 if (sigpending(&sigset) == 0 &&
1171 sigismember(&sigset, SIGPIPE))
1173 sigset_t sigpipe_sigset;
1175 sigemptyset(&sigpipe_sigset);
1176 sigaddset(&sigpipe_sigset, SIGPIPE);
1178 sigwait(&sigpipe_sigset, &signo);
1182 /* Restore saved block mask */
1183 pthread_sigmask(SIG_SETMASK, osigset, NULL);
1185 SOCK_ERRNO_SET(save_errno);
1188 #endif /* ENABLE_THREAD_SAFETY && !WIN32 */