summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2003-06-09 17:59:19 +0000
committerTom Lane2003-06-09 17:59:19 +0000
commitcdfb3d99811d4b1c99c2e0c29ff8cba5043f0c91 (patch)
tree87b92fbdf9854bd77bc420a4fae1cc6eb25a4e9d
parent2df532d9a2b79f27f17235b3b125bd0ab977b7d8 (diff)
freeaddrinfo2() does need two parameters after all, per comment by
Kurt Roeckx. Add some documentation to try to prevent others from repeating my mistake.
-rw-r--r--src/backend/libpq/ip.c49
-rw-r--r--src/backend/libpq/pqcomm.c17
-rw-r--r--src/include/libpq/ip.h4
-rw-r--r--src/interfaces/libpq/fe-connect.c9
-rw-r--r--src/interfaces/libpq/libpq-int.h3
5 files changed, 48 insertions, 34 deletions
diff --git a/src/backend/libpq/ip.c b/src/backend/libpq/ip.c
index 83a5145c363..948fb576141 100644
--- a/src/backend/libpq/ip.c
+++ b/src/backend/libpq/ip.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/ip.c,v 1.8 2003/06/08 17:42:59 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/ip.c,v 1.9 2003/06/09 17:59:19 tgl Exp $
*
* This file and the IPV6 implementation were initially provided by
* Nigel Kukard <[email protected]>, Linux Based Systems Design
@@ -73,26 +73,34 @@ getaddrinfo2(const char *hostname, const char *servname,
/*
* freeaddrinfo2 - free addrinfo structures for IPv4, IPv6, or Unix
+ *
+ * Note: the ai_family field of the original hint structure must be passed
+ * so that we can tell whether the addrinfo struct was built by the system's
+ * getaddrinfo() routine or our own getaddrinfo_unix() routine. Some versions
+ * of getaddrinfo() might be willing to return AF_UNIX addresses, so it's
+ * not safe to look at ai_family in the addrinfo itself.
*/
void
-freeaddrinfo2(struct addrinfo *ai)
+freeaddrinfo2(int hint_ai_family, struct addrinfo *ai)
{
- if (ai != NULL)
- {
#ifdef HAVE_UNIX_SOCKETS
- if (ai->ai_family == AF_UNIX)
+ if (hint_ai_family == AF_UNIX)
+ {
+ /* struct was built by getaddrinfo_unix (see getaddrinfo2) */
+ while (ai != NULL)
{
- while (ai != NULL)
- {
- struct addrinfo *p = ai;
-
- ai = ai->ai_next;
- free(p->ai_addr);
- free(p);
- }
+ struct addrinfo *p = ai;
+
+ ai = ai->ai_next;
+ free(p->ai_addr);
+ free(p);
}
- else
+ }
+ else
#endif /* HAVE_UNIX_SOCKETS */
+ {
+ /* struct was built by getaddrinfo() */
+ if (ai != NULL)
freeaddrinfo(ai);
}
}
@@ -115,6 +123,8 @@ getaddrinfo_unix(const char *path, const struct addrinfo *hintsp,
struct addrinfo *aip;
struct sockaddr_un *unp;
+ *result = NULL;
+
MemSet(&hints, 0, sizeof(hints));
if (hintsp == NULL)
@@ -138,6 +148,13 @@ getaddrinfo_unix(const char *path, const struct addrinfo *hintsp,
if (aip == NULL)
return EAI_MEMORY;
+ unp = calloc(1, sizeof(struct sockaddr_un));
+ if (unp == NULL)
+ {
+ free(aip);
+ return EAI_MEMORY;
+ }
+
aip->ai_family = AF_UNIX;
aip->ai_socktype = hints.ai_socktype;
aip->ai_protocol = hints.ai_protocol;
@@ -145,10 +162,6 @@ getaddrinfo_unix(const char *path, const struct addrinfo *hintsp,
aip->ai_canonname = NULL;
*result = aip;
- unp = calloc(1, sizeof(struct sockaddr_un));
- if (aip == NULL)
- return EAI_MEMORY;
-
unp->sun_family = AF_UNIX;
aip->ai_addr = (struct sockaddr *) unp;
aip->ai_addrlen = sizeof(struct sockaddr_un);
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 39689e4077b..ea4ff644686 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -30,7 +30,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.155 2003/06/08 17:43:00 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.156 2003/06/09 17:59:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -242,7 +242,7 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
{
elog(LOG, "server socket failure: getaddrinfo2(): %s",
gai_strerror(ret));
- freeaddrinfo2(addrs);
+ freeaddrinfo2(hint.ai_family, addrs);
return STATUS_ERROR;
}
@@ -250,7 +250,7 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
{
elog(LOG, "server socket failure: socket(): %s",
strerror(errno));
- freeaddrinfo2(addrs);
+ freeaddrinfo2(hint.ai_family, addrs);
return STATUS_ERROR;
}
@@ -261,7 +261,7 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
{
elog(LOG, "server socket failure: setsockopt(SO_REUSEADDR): %s",
strerror(errno));
- freeaddrinfo2(addrs);
+ freeaddrinfo2(hint.ai_family, addrs);
return STATUS_ERROR;
}
}
@@ -278,7 +278,7 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
sock_path);
else
elog(LOG, "\tIf not, wait a few seconds and retry.");
- freeaddrinfo2(addrs);
+ freeaddrinfo2(hint.ai_family, addrs);
return STATUS_ERROR;
}
@@ -287,7 +287,7 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
{
if (Setup_AF_UNIX() != STATUS_OK)
{
- freeaddrinfo2(addrs);
+ freeaddrinfo2(hint.ai_family, addrs);
return STATUS_ERROR;
}
}
@@ -307,14 +307,13 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
{
elog(LOG, "server socket failure: listen(): %s",
strerror(errno));
- freeaddrinfo2(addrs);
+ freeaddrinfo2(hint.ai_family, addrs);
return STATUS_ERROR;
}
*fdP = fd;
- freeaddrinfo2(addrs);
+ freeaddrinfo2(hint.ai_family, addrs);
return STATUS_OK;
-
}
diff --git a/src/include/libpq/ip.h b/src/include/libpq/ip.h
index 78f52376143..7e910d5cbb2 100644
--- a/src/include/libpq/ip.h
+++ b/src/include/libpq/ip.h
@@ -5,7 +5,7 @@
*
* Copyright (c) 2003, PostgreSQL Global Development Group
*
- * $Id: ip.h,v 1.4 2003/06/08 17:43:00 tgl Exp $
+ * $Id: ip.h,v 1.5 2003/06/09 17:59:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,7 +19,7 @@
extern int getaddrinfo2(const char *hostname, const char *servname,
const struct addrinfo *hintp,
struct addrinfo **result);
-extern void freeaddrinfo2(struct addrinfo *ai);
+extern void freeaddrinfo2(int hint_ai_family, struct addrinfo *ai);
extern char *SockAddr_ntop(const SockAddr *sa, char *dst, size_t cnt,
int v4conv);
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 6eefd9bfcb0..64e39c7baf3 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.242 2003/06/08 17:43:00 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.243 2003/06/09 17:59:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -848,7 +848,7 @@ connectDBStart(PGconn *conn)
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("getaddrinfo() failed: %s\n"),
gai_strerror(ret));
- freeaddrinfo2(addrs);
+ freeaddrinfo2(hint.ai_family, addrs);
goto connect_errReturn;
}
@@ -857,6 +857,7 @@ connectDBStart(PGconn *conn)
*/
conn->addrlist = addrs;
conn->addr_cur = addrs;
+ conn->addrlist_family = hint.ai_family;
conn->pversion = PG_PROTOCOL(3,0);
conn->status = CONNECTION_NEEDED;
@@ -1686,7 +1687,7 @@ retry_ssl_read:
}
/* We can release the address list now. */
- freeaddrinfo2(conn->addrlist);
+ freeaddrinfo2(conn->addrlist_family, conn->addrlist);
conn->addrlist = NULL;
conn->addr_cur = NULL;
@@ -1858,7 +1859,7 @@ freePGconn(PGconn *conn)
/* Note that conn->Pfdebug is not ours to close or free */
if (conn->notifyList)
DLFreeList(conn->notifyList);
- freeaddrinfo2(conn->addrlist);
+ freeaddrinfo2(conn->addrlist_family, conn->addrlist);
if (conn->lobjfuncs)
free(conn->lobjfuncs);
if (conn->inBuffer)
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index eafd4c30935..f710f58b8e4 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: libpq-int.h,v 1.71 2003/06/08 17:43:00 tgl Exp $
+ * $Id: libpq-int.h,v 1.72 2003/06/09 17:59:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -270,6 +270,7 @@ struct pg_conn
/* Transient state needed while establishing connection */
struct addrinfo *addrlist; /* list of possible backend addresses */
struct addrinfo *addr_cur; /* the one currently being tried */
+ int addrlist_family; /* needed to know how to free addrlist */
PGSetenvStatusType setenv_state; /* for 2.0 protocol only */
const PQEnvironmentOption *next_eo;