aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/libpq.sgml11
-rw-r--r--src/interfaces/libpq/fe-connect.c49
-rw-r--r--src/interfaces/libpq/fe-misc.c24
-rw-r--r--src/interfaces/libpq/fe-protocol3.c3
-rw-r--r--src/interfaces/libpq/libpq-int.h3
5 files changed, 54 insertions, 36 deletions
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 2e13e1daa4f..0aa134f4cde 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.265 2008/09/22 14:21:44 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.266 2008/10/27 09:42:31 mha Exp $ -->
<chapter id="libpq">
<title><application>libpq</application> - C Library</title>
@@ -1137,10 +1137,11 @@ PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg);
Nearly all <application>libpq</> functions will set a message for
<function>PQerrorMessage</function> if they fail. Note that by
<application>libpq</application> convention, a nonempty
- <function>PQerrorMessage</function> result will include a trailing
- newline. The caller should not free the result directly. It will
- be freed when the associated <structname>PGconn</> handle is passed
- to <function>PQfinish</function>. The result string should not be
+ <function>PQerrorMessage</function> result can be multiple lines,
+ and will include a trailing newline. The caller should not free
+ the result directly. It will be freed when the associated
+ <structname>PGconn</> handle is passed to
+ <function>PQfinish</function>. The result string should not be
expected to remain the same across operations on the
<literal>PGconn</> structure.
</para>
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 54aa7103970..c611c0de1cb 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.363 2008/10/23 16:17:19 mha Exp $
+ * $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.364 2008/10/27 09:42:31 mha Exp $
*
*-------------------------------------------------------------------------
*/
@@ -699,7 +699,7 @@ connectNoDelay(PGconn *conn)
{
char sebuf[256];
- printfPQExpBuffer(&conn->errorMessage,
+ appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not set socket to TCP no delay mode: %s\n"),
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
return 0;
@@ -729,7 +729,7 @@ connectFailureMessage(PGconn *conn, int errorno)
NULL, 0,
service, sizeof(service),
NI_NUMERICSERV);
- printfPQExpBuffer(&conn->errorMessage,
+ appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not connect to server: %s\n"
"\tIs the server running locally and accepting\n"
"\tconnections on Unix domain socket \"%s\"?\n"),
@@ -739,7 +739,7 @@ connectFailureMessage(PGconn *conn, int errorno)
else
#endif /* HAVE_UNIX_SOCKETS */
{
- printfPQExpBuffer(&conn->errorMessage,
+ appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not connect to server: %s\n"
"\tIs the server running on host \"%s\" and accepting\n"
"\tTCP/IP connections on port %s?\n"),
@@ -829,11 +829,11 @@ connectDBStart(PGconn *conn)
if (ret || !addrs)
{
if (node)
- printfPQExpBuffer(&conn->errorMessage,
+ appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not translate host name \"%s\" to address: %s\n"),
node, gai_strerror(ret));
else
- printfPQExpBuffer(&conn->errorMessage,
+ appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not translate Unix-domain socket path \"%s\" to address: %s\n"),
portstr, gai_strerror(ret));
if (addrs)
@@ -924,6 +924,8 @@ connectDBComplete(PGconn *conn)
switch (flag)
{
case PGRES_POLLING_OK:
+ /* Reset stored error messages since we now have a working connection */
+ resetPQExpBuffer(&conn->errorMessage);
return 1; /* success! */
case PGRES_POLLING_READING:
@@ -1033,7 +1035,7 @@ PQconnectPoll(PGconn *conn)
break;
default:
- printfPQExpBuffer(&conn->errorMessage,
+ appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
"invalid connection state, "
"probably indicative of memory corruption\n"
@@ -1077,7 +1079,7 @@ keep_going: /* We will come back to here until there is
conn->addr_cur = addr_cur->ai_next;
continue;
}
- printfPQExpBuffer(&conn->errorMessage,
+ appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not create socket: %s\n"),
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
break;
@@ -1100,7 +1102,7 @@ keep_going: /* We will come back to here until there is
}
if (!pg_set_noblock(conn->sock))
{
- printfPQExpBuffer(&conn->errorMessage,
+ appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not set socket to non-blocking mode: %s\n"),
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
closesocket(conn->sock);
@@ -1112,7 +1114,7 @@ keep_going: /* We will come back to here until there is
#ifdef F_SETFD
if (fcntl(conn->sock, F_SETFD, FD_CLOEXEC) == -1)
{
- printfPQExpBuffer(&conn->errorMessage,
+ appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not set socket to close-on-exec mode: %s\n"),
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
closesocket(conn->sock);
@@ -1199,7 +1201,7 @@ keep_going: /* We will come back to here until there is
if (getsockopt(conn->sock, SOL_SOCKET, SO_ERROR,
(char *) &optval, &optlen) == -1)
{
- printfPQExpBuffer(&conn->errorMessage,
+ appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not get socket error status: %s\n"),
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
goto error_return;
@@ -1237,7 +1239,7 @@ keep_going: /* We will come back to here until there is
(struct sockaddr *) & conn->laddr.addr,
&conn->laddr.salen) < 0)
{
- printfPQExpBuffer(&conn->errorMessage,
+ appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not get client address from socket: %s\n"),
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
goto error_return;
@@ -1281,7 +1283,7 @@ keep_going: /* We will come back to here until there is
pv = htonl(NEGOTIATE_SSL_CODE);
if (pqPacketSend(conn, 0, &pv, sizeof(pv)) != STATUS_OK)
{
- printfPQExpBuffer(&conn->errorMessage,
+ appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not send SSL negotiation packet: %s\n"),
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
goto error_return;
@@ -1303,6 +1305,7 @@ keep_going: /* We will come back to here until there is
EnvironmentOptions);
if (!startpacket)
{
+ /* will not appendbuffer here, since it's likely to also run out of memory */
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("out of memory\n"));
goto error_return;
@@ -1316,7 +1319,7 @@ keep_going: /* We will come back to here until there is
*/
if (pqPacketSend(conn, 0, startpacket, packetlen) != STATUS_OK)
{
- printfPQExpBuffer(&conn->errorMessage,
+ appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not send startup packet: %s\n"),
SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
free(startpacket);
@@ -1381,7 +1384,7 @@ keep_going: /* We will come back to here until there is
if (conn->sslmode[0] == 'r') /* "require" */
{
/* Require SSL, but server does not want it */
- printfPQExpBuffer(&conn->errorMessage,
+ appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("server does not support SSL, but SSL was required\n"));
goto error_return;
}
@@ -1398,7 +1401,7 @@ keep_going: /* We will come back to here until there is
if (conn->sslmode[0] == 'r') /* "require" */
{
/* Require SSL, but server is too old */
- printfPQExpBuffer(&conn->errorMessage,
+ appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("server does not support SSL, but SSL was required\n"));
goto error_return;
}
@@ -1414,7 +1417,7 @@ keep_going: /* We will come back to here until there is
}
else
{
- printfPQExpBuffer(&conn->errorMessage,
+ appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("received invalid response to SSL negotiation: %c\n"),
SSLok);
goto error_return;
@@ -1489,7 +1492,7 @@ keep_going: /* We will come back to here until there is
*/
if (!(beresp == 'R' || beresp == 'E'))
{
- printfPQExpBuffer(&conn->errorMessage,
+ appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
"expected authentication request from "
"server, but received %c\n"),
@@ -1522,7 +1525,7 @@ keep_going: /* We will come back to here until there is
*/
if (beresp == 'R' && (msgLength < 8 || msgLength > 2000))
{
- printfPQExpBuffer(&conn->errorMessage,
+ appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
"expected authentication request from "
"server, but received %c\n"),
@@ -1534,7 +1537,7 @@ keep_going: /* We will come back to here until there is
{
/* Handle error from a pre-3.0 server */
conn->inCursor = conn->inStart + 1; /* reread data */
- if (pqGets(&conn->errorMessage, conn))
+ if (pqGets_append(&conn->errorMessage, conn))
{
/* We'll come back when there is more data */
return PGRES_POLLING_READING;
@@ -1601,7 +1604,7 @@ keep_going: /* We will come back to here until there is
}
else
{
- if (pqGets(&conn->errorMessage, conn))
+ if (pqGets_append(&conn->errorMessage, conn))
{
/* We'll come back when there is more data */
return PGRES_POLLING_READING;
@@ -1788,7 +1791,7 @@ keep_going: /* We will come back to here until there is
if (res)
{
if (res->resultStatus != PGRES_FATAL_ERROR)
- printfPQExpBuffer(&conn->errorMessage,
+ appendPQExpBuffer(&conn->errorMessage,
libpq_gettext("unexpected message from server during startup\n"));
/*
@@ -1855,7 +1858,7 @@ keep_going: /* We will come back to here until there is
return PGRES_POLLING_OK;
default:
- printfPQExpBuffer(&conn->errorMessage,
+ appendPQExpBuffer(&conn->errorMessage,
libpq_gettext(
"invalid connection state %c, "
"probably indicative of memory corruption\n"
diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c
index cc3e758ef2e..691262cf8ab 100644
--- a/src/interfaces/libpq/fe-misc.c
+++ b/src/interfaces/libpq/fe-misc.c
@@ -23,7 +23,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/interfaces/libpq/fe-misc.c,v 1.135 2008/08/20 11:53:45 mha Exp $
+ * $PostgreSQL: pgsql/src/interfaces/libpq/fe-misc.c,v 1.136 2008/10/27 09:42:31 mha Exp $
*
*-------------------------------------------------------------------------
*/
@@ -106,14 +106,14 @@ pqPutc(char c, PGconn *conn)
/*
- * pqGets:
+ * pqGets[_append]:
* get a null-terminated string from the connection,
* and store it in an expansible PQExpBuffer.
* If we run out of memory, all of the string is still read,
* but the excess characters are silently discarded.
*/
-int
-pqGets(PQExpBuffer buf, PGconn *conn)
+static int
+pqGets_internal(PQExpBuffer buf, PGconn *conn, bool resetbuffer)
{
/* Copy conn data to locals for faster search loop */
char *inBuffer = conn->inBuffer;
@@ -129,7 +129,9 @@ pqGets(PQExpBuffer buf, PGconn *conn)
slen = inCursor - conn->inCursor;
- resetPQExpBuffer(buf);
+ if (resetbuffer)
+ resetPQExpBuffer(buf);
+
appendBinaryPQExpBuffer(buf, inBuffer + conn->inCursor, slen);
conn->inCursor = ++inCursor;
@@ -141,6 +143,18 @@ pqGets(PQExpBuffer buf, PGconn *conn)
return 0;
}
+int
+pqGets(PQExpBuffer buf, PGconn *conn)
+{
+ return pqGets_internal(buf, conn, true);
+}
+
+int
+pqGets_append(PQExpBuffer buf, PGconn *conn)
+{
+ return pqGets_internal(buf, conn, false);
+}
+
/*
* pqPuts: write a null-terminated string to the current message
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 66059493bb0..ba2798234f0 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/interfaces/libpq/fe-protocol3.c,v 1.35 2008/05/29 22:02:44 tgl Exp $
+ * $PostgreSQL: pgsql/src/interfaces/libpq/fe-protocol3.c,v 1.36 2008/10/27 09:42:31 mha Exp $
*
*-------------------------------------------------------------------------
*/
@@ -853,7 +853,6 @@ pqGetErrorNotice3(PGconn *conn, bool isError)
goto fail;
pqClearAsyncResult(conn);
conn->result = res;
- resetPQExpBuffer(&conn->errorMessage);
appendPQExpBufferStr(&conn->errorMessage, workBuf.data);
}
else
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 9702c616820..8525fb15f05 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.134 2008/09/22 14:21:44 tgl Exp $
+ * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.135 2008/10/27 09:42:31 mha Exp $
*
*-------------------------------------------------------------------------
*/
@@ -519,6 +519,7 @@ extern int pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn);
extern int pqGetc(char *result, PGconn *conn);
extern int pqPutc(char c, PGconn *conn);
extern int pqGets(PQExpBuffer buf, PGconn *conn);
+extern int pqGets_append(PQExpBuffer buf, PGconn *conn);
extern int pqPuts(const char *s, PGconn *conn);
extern int pqGetnchar(char *s, size_t len, PGconn *conn);
extern int pqPutnchar(const char *s, size_t len, PGconn *conn);