Thom Brown reported that SSL connections didn't seem to work on Windows in
9.5. Asif Naeem figured out that the cause was my_sock_read() looking at
"errno" when it needs to look at "SOCK_ERRNO". This mistake was introduced
in commit
680513ab79c7e12e402a2aad7921b95a25a4bcc8, which cloned the
backend's custom SSL BIO code into libpq, and didn't translate the errno
handling properly. Moreover, it introduced unnecessary errno save/restore
logic, which was particularly confusing because it was incomplete; and it
failed to check for all three of EINTR, EAGAIN, and EWOULDBLOCK in
my_sock_write. (That might not be necessary; but since we're copying
well-tested backend code that does do that, it seems prudent to copy it
faithfully.)
my_sock_read(BIO *h, char *buf, int size)
{
int res;
- int save_errno;
res = pqsecure_raw_read((PGconn *) h->ptr, buf, size);
- save_errno = errno;
BIO_clear_retry_flags(h);
if (res < 0)
{
- switch (save_errno)
+ /* If we were interrupted, tell caller to retry */
+ switch (SOCK_ERRNO)
{
#ifdef EAGAIN
case EAGAIN:
}
}
- errno = save_errno;
return res;
}
my_sock_write(BIO *h, const char *buf, int size)
{
int res;
- int save_errno;
res = pqsecure_raw_write((PGconn *) h->ptr, buf, size);
- save_errno = errno;
BIO_clear_retry_flags(h);
if (res <= 0)
{
- if (save_errno == EINTR)
+ /* If we were interrupted, tell caller to retry */
+ switch (SOCK_ERRNO)
{
- BIO_set_retry_write(h);
+#ifdef EAGAIN
+ case EAGAIN:
+#endif
+#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
+ case EWOULDBLOCK:
+#endif
+ case EINTR:
+ BIO_set_retry_write(h);
+ break;
+
+ default:
+ break;
}
}