From 5d305d86bd917723f09ab4f15c075d90586a210a Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Wed, 16 Apr 2014 19:46:51 -0400
Subject: [PATCH] libpq:  use pgsocket for socket values, for portability

Previously, 'int' was used for socket values in libpq, but socket values
are unsigned on Windows.  This is a style correction.

Initial patch and previous PGINVALID_SOCKET initial patch by Joel
Jacobson, modified by me

Report from PVS-Studio
---
 src/interfaces/libpq/fe-connect.c   | 34 ++++++++---------------------
 src/interfaces/libpq/fe-exec.c      |  2 +-
 src/interfaces/libpq/fe-misc.c      |  6 ++---
 src/interfaces/libpq/fe-protocol2.c |  2 +-
 src/interfaces/libpq/fe-protocol3.c |  2 +-
 src/interfaces/libpq/libpq-int.h    |  2 +-
 6 files changed, 16 insertions(+), 32 deletions(-)

diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 5d1e45629c..10cc0e69b2 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -398,9 +398,9 @@ pqDropConnection(PGconn *conn)
 	/* Drop any SSL state */
 	pqsecure_close(conn);
 	/* Close the socket itself */
-	if (conn->sock >= 0)
+	if (conn->sock != PGINVALID_SOCKET)
 		closesocket(conn->sock);
-	conn->sock = -1;
+	conn->sock = PGINVALID_SOCKET;
 	/* Discard any unread/unsent data */
 	conn->inStart = conn->inCursor = conn->inEnd = 0;
 	conn->outCount = 0;
@@ -1631,24 +1631,8 @@ keep_going:						/* We will come back to here until there is
 						   addr_cur->ai_addrlen);
 					conn->raddr.salen = addr_cur->ai_addrlen;
 
-					/* Open a socket */
-					{
-						/*
-						 * While we use 'pgsocket' as the socket type in the
-						 * backend, we use 'int' for libpq socket values.
-						 * This requires us to map PGINVALID_SOCKET to -1
-						 * on Windows.
-						 * See http://msdn.microsoft.com/en-us/library/windows/desktop/ms740516%28v=vs.85%29.aspx
-						 */
-						pgsocket sock = socket(addr_cur->ai_family, SOCK_STREAM, 0);
-#ifdef WIN32
-						if (sock == PGINVALID_SOCKET)
-							conn->sock = -1;
-						else
-#endif
-							conn->sock = sock;
-					}
-					if (conn->sock == -1)
+					conn->sock = socket(addr_cur->ai_family, SOCK_STREAM, 0);
+					if (conn->sock == PGINVALID_SOCKET)
 					{
 						/*
 						 * ignore socket() failure if we have more addresses
@@ -2717,7 +2701,7 @@ makeEmptyPGconn(void)
 	conn->client_encoding = PG_SQL_ASCII;
 	conn->std_strings = false;	/* unless server says differently */
 	conn->verbosity = PQERRORS_DEFAULT;
-	conn->sock = -1;
+	conn->sock = PGINVALID_SOCKET;
 	conn->auth_req_received = false;
 	conn->password_needed = false;
 	conn->dot_pgpass_used = false;
@@ -2882,7 +2866,7 @@ closePGconn(PGconn *conn)
 	 * Note that the protocol doesn't allow us to send Terminate messages
 	 * during the startup phase.
 	 */
-	if (conn->sock >= 0 && conn->status == CONNECTION_OK)
+	if (conn->sock != PGINVALID_SOCKET && conn->status == CONNECTION_OK)
 	{
 		/*
 		 * Try to send "close connection" message to backend. Ignore any
@@ -3103,7 +3087,7 @@ PQgetCancel(PGconn *conn)
 	if (!conn)
 		return NULL;
 
-	if (conn->sock < 0)
+	if (conn->sock == PGINVALID_SOCKET)
 		return NULL;
 
 	cancel = malloc(sizeof(PGcancel));
@@ -3284,7 +3268,7 @@ PQrequestCancel(PGconn *conn)
 	if (!conn)
 		return FALSE;
 
-	if (conn->sock < 0)
+	if (conn->sock == PGINVALID_SOCKET)
 	{
 		strlcpy(conn->errorMessage.data,
 				"PQrequestCancel() -- connection is not open\n",
@@ -5361,7 +5345,7 @@ PQsocket(const PGconn *conn)
 {
 	if (!conn)
 		return -1;
-	return conn->sock;
+	return (conn->sock != PGINVALID_SOCKET) ? conn->sock : -1;
 }
 
 int
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 8ccf6d39ee..50e4035781 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -2549,7 +2549,7 @@ PQfn(PGconn *conn,
 	/* clear the error string */
 	resetPQExpBuffer(&conn->errorMessage);
 
-	if (conn->sock < 0 || conn->asyncStatus != PGASYNC_IDLE ||
+	if (conn->sock == PGINVALID_SOCKET || conn->asyncStatus != PGASYNC_IDLE ||
 		conn->result != NULL)
 	{
 		printfPQExpBuffer(&conn->errorMessage,
diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c
index a7afd42556..cc487b22ee 100644
--- a/src/interfaces/libpq/fe-misc.c
+++ b/src/interfaces/libpq/fe-misc.c
@@ -604,7 +604,7 @@ pqReadData(PGconn *conn)
 	int			someread = 0;
 	int			nread;
 
-	if (conn->sock < 0)
+	if (conn->sock == PGINVALID_SOCKET)
 	{
 		printfPQExpBuffer(&conn->errorMessage,
 						  libpq_gettext("connection not open\n"));
@@ -800,7 +800,7 @@ pqSendSome(PGconn *conn, int len)
 	int			remaining = conn->outCount;
 	int			result = 0;
 
-	if (conn->sock < 0)
+	if (conn->sock == PGINVALID_SOCKET)
 	{
 		printfPQExpBuffer(&conn->errorMessage,
 						  libpq_gettext("connection not open\n"));
@@ -1011,7 +1011,7 @@ pqSocketCheck(PGconn *conn, int forRead, int forWrite, time_t end_time)
 
 	if (!conn)
 		return -1;
-	if (conn->sock < 0)
+	if (conn->sock == PGINVALID_SOCKET)
 	{
 		printfPQExpBuffer(&conn->errorMessage,
 						  libpq_gettext("socket not open\n"));
diff --git a/src/interfaces/libpq/fe-protocol2.c b/src/interfaces/libpq/fe-protocol2.c
index f3fddaa036..10510b5bf5 100644
--- a/src/interfaces/libpq/fe-protocol2.c
+++ b/src/interfaces/libpq/fe-protocol2.c
@@ -1211,7 +1211,7 @@ pqGetline2(PGconn *conn, char *s, int maxlen)
 {
 	int			result = 1;		/* return value if buffer overflows */
 
-	if (conn->sock < 0 ||
+	if (conn->sock == PGINVALID_SOCKET ||
 		conn->asyncStatus != PGASYNC_COPY_OUT)
 	{
 		*s = '\0';
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 47cd7f487f..d895589148 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -1568,7 +1568,7 @@ pqGetline3(PGconn *conn, char *s, int maxlen)
 {
 	int			status;
 
-	if (conn->sock < 0 ||
+	if (conn->sock == PGINVALID_SOCKET ||
 		(conn->asyncStatus != PGASYNC_COPY_OUT &&
 		 conn->asyncStatus != PGASYNC_COPY_BOTH) ||
 		conn->copy_is_binary)
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index ee975d41fa..0725c17023 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -365,7 +365,7 @@ struct pg_conn
 
 	/* Connection data */
 	/* See PQconnectPoll() for how we use 'int' and not 'pgsocket'. */
-	int			sock;			/* Unix FD for socket, -1 if not connected */
+	pgsocket	sock;			/* FD for socket, PGINVALID_SOCKET if unconnected */
 	SockAddr	laddr;			/* Local address */
 	SockAddr	raddr;			/* Remote address */
 	ProtocolVersion pversion;	/* FE/BE protocol version in use */