From 4717992b4e6b3c752b8e07465011fe68da7e32b8 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Thu, 6 Jan 2005 20:06:58 +0000
Subject: [PATCH] Instead of a bare recv() to read the server's response to an
 SSL request packet, use pqReadData().  This has the same effect since
 conn->ssl isn't set yet and we aren't expecting more than one byte. The
 advantage is that we will correctly detect loss-of-connection instead of
 going into an infinite loop.  Per report from Hannu Krosing.

---
 src/interfaces/libpq/fe-connect.c | 36 ++++++++++++++++++-------------
 1 file changed, 21 insertions(+), 15 deletions(-)

diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 908c39c256..2949cf64a3 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.297 2005/01/06 18:29:10 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.298 2005/01/06 20:06:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1452,30 +1452,36 @@ keep_going:						/* We will come back to here until there
 
 				/*
 				 * On first time through, get the postmaster's response to
-				 * our SSL negotiation packet.	Be careful to read only
-				 * one byte (if there's more, it could be SSL data).
+				 * our SSL negotiation packet.
 				 */
 				if (conn->ssl == NULL)
 				{
+					/*
+					 * We use pqReadData here since it has the logic to
+					 * distinguish no-data-yet from connection closure.
+					 * Since conn->ssl isn't set, a plain recv() will occur.
+					 */
 					char		SSLok;
-					int			nread;
+					int			rdresult;
 
-			retry_ssl_read:
-					nread = recv(conn->sock, &SSLok, 1, 0);
-					if (nread < 0)
+					rdresult = pqReadData(conn);
+					if (rdresult < 0)
 					{
-						if (SOCK_ERRNO == EINTR)
-							/* Interrupted system call - just try again */
-							goto retry_ssl_read;
-
-						printfPQExpBuffer(&conn->errorMessage,
-										  libpq_gettext("could not receive server response to SSL negotiation packet: %s\n"),
-						SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
+						/* errorMessage is already filled in */
 						goto error_return;
 					}
-					if (nread == 0)
+					if (rdresult == 0)
+					{
 						/* caller failed to wait for data */
 						return PGRES_POLLING_READING;
+					}
+					if (pqGetc(&SSLok, conn) < 0)
+					{
+						/* should not happen really */
+						return PGRES_POLLING_READING;
+					}
+					/* mark byte consumed */
+					conn->inStart = conn->inCursor;
 					if (SSLok == 'S')
 					{
 						/* Do one-time setup; this creates conn->ssl */
-- 
2.24.1