]> granicus.if.org Git - postgresql/commitdiff
freeaddrinfo2() does need two parameters after all, per comment by
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 9 Jun 2003 17:59:19 +0000 (17:59 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 9 Jun 2003 17:59:19 +0000 (17:59 +0000)
Kurt Roeckx.  Add some documentation to try to prevent others from
repeating my mistake.

src/backend/libpq/ip.c
src/backend/libpq/pqcomm.c
src/include/libpq/ip.h
src/interfaces/libpq/fe-connect.c
src/interfaces/libpq/libpq-int.h

index 83a5145c363534778d7ee4b01c67f2c5354a8df2..948fb5761414abd3bcb87ac55ffca1ae00557ccd 100644 (file)
@@ -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);
index 39689e4077b7acb3585ef387bdb725c89104cf91..ea4ff64468643774728f103f61fd14b07ed4be50 100644 (file)
@@ -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;
-
 }
 
 
index 78f52376143b7eb0fc4fd7063ca86e4dba855116..7e910d5cbb2796a96762febc597d8d9d55180859 100644 (file)
@@ -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);
index 6eefd9bfcb0fb0f6a83ebb4fa8dce454144f208a..64e39c7baf3e6844b36d66e5cba2a7b8b70078de 100644 (file)
@@ -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)
index eafd4c3093559ac77c11aeea82440c490ae23ed9..f710f58b8e49bf20f6ecd6e7cbb531760aee2332 100644 (file)
@@ -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;