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;