Improve PQhost() to return useful data for default Unix-socket connections.
authorTom Lane
Fri, 27 Nov 2015 19:13:53 +0000 (14:13 -0500)
committerTom Lane
Fri, 27 Nov 2015 19:13:53 +0000 (14:13 -0500)
Previously, if no host information had been specified at connection time,
PQhost() would return NULL (unless you are on Windows, in which case you
got "localhost").  This is an unhelpful definition for a couple of reasons:
it can cause corner-case crashes in applications (cf commit c5ef8ce53d),
and there's no well-defined way for applications to find out the socket
directory path that's actually in use.  As an example of the latter
problem, psql substituted DEFAULT_PGSOCKET_DIR for NULL in a couple of
places, but this is subtly wrong because it's conceivable that psql is
using a libpq shared library that was built with a different setting.

Hence, change PQhost() to return DEFAULT_PGSOCKET_DIR when appropriate,
and strip out the now-dead substitutions in psql.  (There is still one
remaining reference to DEFAULT_PGSOCKET_DIR in psql, in prompt.c, which
I don't see a nice way to get rid of.  But it only controls a prompt
abbreviation decision, so it seems noncritical.)

Also update the docs for PQhost, which had never previously mentioned
the possibility of a socket directory path being returned.  In passing
fix the outright-incorrect code comment about PGconn.pgunixsocket.

doc/src/sgml/libpq.sgml
src/bin/psql/command.c
src/interfaces/libpq/fe-connect.c
src/interfaces/libpq/libpq-int.h

index cffabbc8f7ec109e5de97e1879e4674b65c7aaff..9c0e4c8f9c6caffd29afce39b9105d5941dde642 100644 (file)
@@ -1463,6 +1463,10 @@ char *PQpass(const PGconn *conn);
      
       
        Returns the server host name of the connection.
+       This can be a host name, an IP address, or a directory path if the
+       connection is via Unix socket.  (The path case can be distinguished
+       because it will always be an absolute path, beginning
+       with /.)
 
 char *PQhost(const PGconn *conn);
 
index 3a82e37401c549159eaf6e24744d7c108ca598fb..438a4ec8ea243e27887ba63cc51bb5773e74eb4c 100644 (file)
@@ -322,8 +322,6 @@ exec_command(const char *cmd,
            PQconninfoOption *option;
 
            host = PQhost(pset.db);
-           if (host == NULL)
-               host = DEFAULT_PGSOCKET_DIR;
            /* A usable "hostaddr" overrides the basic sense of host. */
            connOptions = PQconninfo(pset.db);
            if (connOptions == NULL)
@@ -1750,16 +1748,14 @@ do_connect(char *dbname, char *user, char *host, char *port)
    /*
     * Any change in the parameters read above makes us discard the password.
     * We also discard it if we're to use a conninfo rather than the
-    * positional syntax.  Note that currently, PQhost() can return NULL for a
-    * default Unix-socket connection, so we have to allow NULL for host.
+    * positional syntax.
     */
    if (has_connection_string)
        keep_password = false;
    else
        keep_password =
            (user && PQuser(o_conn) && strcmp(user, PQuser(o_conn)) == 0) &&
-           ((host && PQhost(o_conn) && strcmp(host, PQhost(o_conn)) == 0) ||
-            (host == NULL && PQhost(o_conn) == NULL)) &&
+           (host && PQhost(o_conn) && strcmp(host, PQhost(o_conn)) == 0) &&
            (port && PQport(o_conn) && strcmp(port, PQport(o_conn)) == 0);
 
    /*
@@ -1890,8 +1886,6 @@ do_connect(char *dbname, char *user, char *host, char *port)
        {
            char       *host = PQhost(pset.db);
 
-           if (host == NULL)
-               host = DEFAULT_PGSOCKET_DIR;
            /* If the host is an absolute path, the connection is via socket */
            if (is_absolute_path(host))
                printf(_("You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
index 9c51166b40a5b83ec8e6479191fd48850390e830..4a1a0272b6b833ebcb6d5c9e6e15f8ee5d322850 100644 (file)
@@ -5353,7 +5353,10 @@ PQhost(const PGconn *conn)
    else
    {
 #ifdef HAVE_UNIX_SOCKETS
-       return conn->pgunixsocket;
+       if (conn->pgunixsocket != NULL && conn->pgunixsocket[0] != '\0')
+           return conn->pgunixsocket;
+       else
+           return DEFAULT_PGSOCKET_DIR;
 #else
        return DefaultHost;
 #endif
index 4b69c1216dbe6baaf3d2905d7ce65648cdf0a2ef..98ea6b19477ed7b0be43dbf4f328216399106b02 100644 (file)
@@ -302,10 +302,9 @@ struct pg_conn
    char       *pghostaddr;     /* the numeric IP address of the machine on
                                 * which the server is running.  Takes
                                 * precedence over above. */
-   char       *pgport;         /* the server's communication port */
-   char       *pgunixsocket;   /* the Unix-domain socket that the server is
-                                * listening on; if NULL, uses a default
-                                * constructed from pgport */
+   char       *pgport;         /* the server's communication port number */
+   char       *pgunixsocket;   /* the directory of the server's Unix-domain
+                                * socket; if NULL, use DEFAULT_PGSOCKET_DIR */
    char       *pgtty;          /* tty on which the backend messages is
                                 * displayed (OBSOLETE, NOT USED) */
    char       *connect_timeout;    /* connection timeout (numeric string) */