Commit cdfb3d99 authored by Tom Lane's avatar Tom Lane

freeaddrinfo2() does need two parameters after all, per comment by

Kurt Roeckx.  Add some documentation to try to prevent others from
repeating my mistake.
parent 2df532d9
......@@ -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 <nkukard@lbsd.net>, 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);
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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)
......
......@@ -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;
......
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