Fabien COELHO <coe...@cri.ensmp.fr> writes: > Patch compiles, global "make check" ok, although I'm unsure whether the > feature is actually tested somewhere. I think not:-(
Yeah, it's hard to test this stuff without either opening up security hazards or making unwarranted assumptions about the local network setup. I think that the standard regression tests only use Unix-socket communication (except on Windows) for exactly that reason, and that makes it hard to do anything much about regression-testing this feature. > As you noted in another message, a small doc update should be needed. Check. Proposed doc patch attached. (Only the last hunk is actually specific to this patch, the rest is cleanup that I noticed while looking around for possibly-relevant text.) > I'd consider wrapping some of the logic. I'd check the port first, then > move the host resolution stuff into a function. Don't really see the value of either ... regards, tom lane
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index 80e55f5..7c150f3 100644 *** a/doc/src/sgml/libpq.sgml --- b/doc/src/sgml/libpq.sgml *************** PostgresPollingStatusType PQconnectPoll( *** 303,311 **** <itemizedlist> <listitem> <para> ! The <literal>hostaddr</literal> and <literal>host</literal> parameters are used appropriately to ensure that ! name and reverse name queries are not made. See the documentation of ! these parameters in <xref linkend="libpq-paramkeywords"/> for details. </para> </listitem> --- 303,311 ---- <itemizedlist> <listitem> <para> ! The <literal>hostaddr</literal> parameter must be used appropriately ! to prevent DNS queries from being made. See the documentation of ! this parameter in <xref linkend="libpq-paramkeywords"/> for details. </para> </listitem> *************** PostgresPollingStatusType PQconnectPoll( *** 318,324 **** <listitem> <para> ! You ensure that the socket is in the appropriate state before calling <function>PQconnectPoll</function>, as described below. </para> </listitem> --- 318,324 ---- <listitem> <para> ! You must ensure that the socket is in the appropriate state before calling <function>PQconnectPoll</function>, as described below. </para> </listitem> *************** PostgresPollingStatusType PQconnectPoll( *** 326,349 **** </para> <para> ! Note: use of <function>PQconnectStartParams</function> is analogous to ! <function>PQconnectStart</function> shown below. ! </para> ! ! <para> ! To begin a nonblocking connection request, call <literal>conn = PQconnectStart("<replaceable>connection_info_string</replaceable>")</literal>. ! If <varname>conn</varname> is null, then <application>libpq</application> has been unable to allocate a new <structname>PGconn</structname> ! structure. Otherwise, a valid <structname>PGconn</structname> pointer is returned (though not yet ! representing a valid connection to the database). On return from ! <function>PQconnectStart</function>, call <literal>status = PQstatus(conn)</literal>. If <varname>status</varname> equals ! <symbol>CONNECTION_BAD</symbol>, <function>PQconnectStart</function> has failed. </para> <para> ! If <function>PQconnectStart</function> succeeds, the next stage is to poll ! <application>libpq</application> so that it can proceed with the connection sequence. Use <function>PQsocket(conn)</function> to obtain the descriptor of the socket underlying the database connection. Loop thus: If <function>PQconnectPoll(conn)</function> last returned <symbol>PGRES_POLLING_READING</symbol>, wait until the socket is ready to read (as indicated by <function>select()</function>, <function>poll()</function>, or --- 326,352 ---- </para> <para> ! To begin a nonblocking connection request, ! call <function>PQconnectStart</function> ! or <function>PQconnectStartParams</function>. If the result is null, ! then <application>libpq</application> has been unable to allocate a ! new <structname>PGconn</structname> structure. Otherwise, a ! valid <structname>PGconn</structname> pointer is returned (though not ! yet representing a valid connection to the database). Next ! call <literal>PQstatus(conn)</literal>. If the result ! is <symbol>CONNECTION_BAD</symbol>, the connection attempt has already ! failed, typically because of invalid connection parameters. </para> <para> ! If <function>PQconnectStart</function> ! or <function>PQconnectStartParams</function> succeeds, the next stage ! is to poll <application>libpq</application> so that it can proceed with ! the connection sequence. Use <function>PQsocket(conn)</function> to obtain the descriptor of the socket underlying the database connection. + (Caution: do not assume that the socket remains the same + across <function>PQconnectPoll</function> calls.) Loop thus: If <function>PQconnectPoll(conn)</function> last returned <symbol>PGRES_POLLING_READING</symbol>, wait until the socket is ready to read (as indicated by <function>select()</function>, <function>poll()</function>, or *************** PostgresPollingStatusType PQconnectPoll( *** 352,360 **** Conversely, if <function>PQconnectPoll(conn)</function> last returned <symbol>PGRES_POLLING_WRITING</symbol>, wait until the socket is ready to write, then call <function>PQconnectPoll(conn)</function> again. ! If you have yet to call ! <function>PQconnectPoll</function>, i.e., just after the call to ! <function>PQconnectStart</function>, behave as if it last returned <symbol>PGRES_POLLING_WRITING</symbol>. Continue this loop until <function>PQconnectPoll(conn)</function> returns <symbol>PGRES_POLLING_FAILED</symbol>, indicating the connection procedure --- 355,362 ---- Conversely, if <function>PQconnectPoll(conn)</function> last returned <symbol>PGRES_POLLING_WRITING</symbol>, wait until the socket is ready to write, then call <function>PQconnectPoll(conn)</function> again. ! On the first iteration, i.e. if you have yet to call ! <function>PQconnectPoll</function>, behave as if it last returned <symbol>PGRES_POLLING_WRITING</symbol>. Continue this loop until <function>PQconnectPoll(conn)</function> returns <symbol>PGRES_POLLING_FAILED</symbol>, indicating the connection procedure *************** switch(PQstatus(conn)) *** 479,488 **** </para> <para> ! Note that if <function>PQconnectStart</function> returns a non-null pointer, you must call ! <function>PQfinish</function> when you are finished with it, in order to dispose of ! the structure and any associated memory blocks. This must be done even if ! the connection attempt fails or is abandoned. </para> </listitem> </varlistentry> --- 481,492 ---- </para> <para> ! Note that when <function>PQconnectStart</function> ! or <function>PQconnectStartParams</function> returns a non-null ! pointer, you must call <function>PQfinish</function> when you are ! finished with it, in order to dispose of the structure and any ! associated memory blocks. This must be done even if the connection ! attempt fails or is abandoned. </para> </listitem> </varlistentry> *************** postgresql://%2Fvar%2Flib%2Fpostgresql/d *** 913,919 **** It is possible to specify multiple hosts to connect to, so that they are tried in the given order. In the Keyword/Value format, the <literal>host</literal>, <literal>hostaddr</literal>, and <literal>port</literal> options accept a comma-separated ! list of values. The same number of elements must be given in each option, such that e.g. the first <literal>hostaddr</literal> corresponds to the first host name, the second <literal>hostaddr</literal> corresponds to the second host name, and so forth. As an exception, if only one <literal>port</literal> is specified, it --- 917,924 ---- It is possible to specify multiple hosts to connect to, so that they are tried in the given order. In the Keyword/Value format, the <literal>host</literal>, <literal>hostaddr</literal>, and <literal>port</literal> options accept a comma-separated ! list of values. The same number of elements must be given in each ! option that is specified, such that e.g. the first <literal>hostaddr</literal> corresponds to the first host name, the second <literal>hostaddr</literal> corresponds to the second host name, and so forth. As an exception, if only one <literal>port</literal> is specified, it *************** postgresql://%2Fvar%2Flib%2Fpostgresql/d *** 922,930 **** <para> In the connection URI format, you can list multiple <literal>host:port</literal> pairs ! separated by commas, in the <literal>host</literal> component of the URI. In either ! format, a single host name can also translate to multiple network addresses. A ! common example of this is a host that has both an IPv4 and an IPv6 address. </para> <para> --- 927,939 ---- <para> In the connection URI format, you can list multiple <literal>host:port</literal> pairs ! separated by commas, in the <literal>host</literal> component of the URI. ! </para> ! ! <para> ! In either format, a single host name can translate to multiple network ! addresses. A common example of this is a host that has both an IPv4 and ! an IPv6 address. </para> <para> *************** postgresql://%2Fvar%2Flib%2Fpostgresql/d *** 958,966 **** Name of host to connect to.<indexterm><primary>host name</primary></indexterm> If a host name begins with a slash, it specifies Unix-domain communication rather than TCP/IP communication; the value is the ! name of the directory in which the socket file is stored. If ! multiple host names are specified, each will be tried in turn in ! the order given. The default behavior when <literal>host</literal> is not specified, or is empty, is to connect to a Unix-domain socket<indexterm><primary>Unix domain socket</primary></indexterm> in <filename>/tmp</filename> (or whatever socket directory was specified --- 967,974 ---- Name of host to connect to.<indexterm><primary>host name</primary></indexterm> If a host name begins with a slash, it specifies Unix-domain communication rather than TCP/IP communication; the value is the ! name of the directory in which the socket file is stored. ! The default behavior when <literal>host</literal> is not specified, or is empty, is to connect to a Unix-domain socket<indexterm><primary>Unix domain socket</primary></indexterm> in <filename>/tmp</filename> (or whatever socket directory was specified *************** postgresql://%2Fvar%2Flib%2Fpostgresql/d *** 997,1004 **** <itemizedlist> <listitem> <para> ! If <literal>host</literal> is specified without <literal>hostaddr</literal>, ! a host name lookup occurs. </para> </listitem> <listitem> --- 1005,1016 ---- <itemizedlist> <listitem> <para> ! If <literal>host</literal> is specified ! without <literal>hostaddr</literal>, a host name lookup occurs. ! (When using <function>PQconnectPoll</function>, the lookup occurs ! when <function>PQconnectPoll</function> first considers this host ! name, and it may cause <function>PQconnectPoll</function> to block ! for a significant amount of time.) </para> </listitem> <listitem>