Commit 60f1e6bc authored by Tom Lane's avatar Tom Lane

Fix poor errno handling in libpq's version of our custom OpenSSL BIO.

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 680513ab, 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.)
parent 992d702b
......@@ -1598,14 +1598,13 @@ static int
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:
......@@ -1622,7 +1621,6 @@ my_sock_read(BIO *h, char *buf, int size)
}
}
errno = save_errno;
return res;
}
......@@ -1630,16 +1628,26 @@ static int
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;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment