Commit e77aaade authored by Peter Eisentraut's avatar Peter Eisentraut

Repair libpq to follow protocol by not sending Terminate messages before

the startup exchange is complete.  Also make sure that packets defined as
single bytes aren't sent with a trailing '\0'.
parent 9981b0f9
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.164 2001/03/31 23:14:37 tgl Exp $ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.165 2001/07/06 17:58:53 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1409,6 +1409,7 @@ keep_going: /* We will come back to here until there ...@@ -1409,6 +1409,7 @@ keep_going: /* We will come back to here until there
if (areq == AUTH_REQ_OK) if (areq == AUTH_REQ_OK)
{ {
/* We are done with authentication exchange */ /* We are done with authentication exchange */
conn->startup_complete = TRUE;
conn->status = CONNECTION_AUTH_OK; conn->status = CONNECTION_AUTH_OK;
/* /*
...@@ -1909,6 +1910,7 @@ makeEmptyPGconn(void) ...@@ -1909,6 +1910,7 @@ makeEmptyPGconn(void)
freePGconn(conn); freePGconn(conn);
conn = NULL; conn = NULL;
} }
conn->startup_complete = FALSE;
return conn; return conn;
} }
...@@ -1972,7 +1974,9 @@ freePGconn(PGconn *conn) ...@@ -1972,7 +1974,9 @@ freePGconn(PGconn *conn)
static void static void
closePGconn(PGconn *conn) closePGconn(PGconn *conn)
{ {
if (conn->sock >= 0) /* Note that the protocol doesn't allow us to send Terminate
messages during the startup phase. */
if (conn->sock >= 0 && conn->startup_complete)
{ {
/* /*
...@@ -1981,8 +1985,8 @@ closePGconn(PGconn *conn) ...@@ -1981,8 +1985,8 @@ closePGconn(PGconn *conn)
* avoid getting SIGPIPE'd if the connection were already closed. * avoid getting SIGPIPE'd if the connection were already closed.
* Now we rely on pqFlush to avoid the signal. * Now we rely on pqFlush to avoid the signal.
*/ */
(void) pqPuts("X", conn); pqPutc('X', conn);
(void) pqFlush(conn); pqFlush(conn);
} }
/* /*
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.101 2001/02/10 02:31:30 tgl Exp $ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.102 2001/07/06 17:58:53 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -556,8 +556,7 @@ PQsendQuery(PGconn *conn, const char *query) ...@@ -556,8 +556,7 @@ PQsendQuery(PGconn *conn, const char *query)
return 0; return 0;
/* 'Q' == queries */ /* 'Q' == queries */
/* XXX: if we fail here we really ought to not block */ /* XXX: if we fail here we really ought to not block */
if (pqPutnchar("Q", 1, conn) || if (pqPutc('Q', conn) != 0 || pqPuts(query, conn) != 0)
pqPuts(query, conn))
{ {
handleSendFailure(conn); handleSendFailure(conn);
return 0; return 0;
...@@ -567,7 +566,7 @@ PQsendQuery(PGconn *conn, const char *query) ...@@ -567,7 +566,7 @@ PQsendQuery(PGconn *conn, const char *query)
* give the data a push, ignore the return value as ConsumeInput() * give the data a push, ignore the return value as ConsumeInput()
* will do any aditional flushing if needed * will do any aditional flushing if needed
*/ */
(void) pqFlush(conn); pqFlush(conn);
} }
else else
{ {
...@@ -575,9 +574,8 @@ PQsendQuery(PGconn *conn, const char *query) ...@@ -575,9 +574,8 @@ PQsendQuery(PGconn *conn, const char *query)
/* /*
* the frontend-backend protocol uses 'Q' to designate queries * the frontend-backend protocol uses 'Q' to designate queries
*/ */
if (pqPutnchar("Q", 1, conn) || if (pqPutc('Q', conn) != 0 || pqPuts(query, conn) != 0 ||
pqPuts(query, conn) || pqFlush(conn) != 0)
pqFlush(conn))
{ {
handleSendFailure(conn); handleSendFailure(conn);
return 0; return 0;
...@@ -1655,9 +1653,9 @@ PQfn(PGconn *conn, ...@@ -1655,9 +1653,9 @@ PQfn(PGconn *conn,
return NULL; return NULL;
} }
if (pqPuts("F ", conn) || /* function */ if (pqPuts("F ", conn) != 0 || /* function */
pqPutInt(fnid, 4, conn) || /* function id */ pqPutInt(fnid, 4, conn) != 0 || /* function id */
pqPutInt(nargs, 4, conn)) /* # of args */ pqPutInt(nargs, 4, conn) != 0) /* # of args */
{ {
handleSendFailure(conn); handleSendFailure(conn);
return NULL; return NULL;
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.49 2001/05/28 15:29:51 tgl Exp $ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.50 2001/07/06 17:58:53 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -59,6 +59,8 @@ ...@@ -59,6 +59,8 @@
#define DONOTICE(conn,message) \ #define DONOTICE(conn,message) \
((*(conn)->noticeHook) ((conn)->noticeArg, (message))) ((*(conn)->noticeHook) ((conn)->noticeArg, (message)))
static int pqPutBytes(const char *s, size_t nbytes, PGconn *conn);
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/* pqGetc: /* pqGetc:
...@@ -83,6 +85,22 @@ pqGetc(char *result, PGconn *conn) ...@@ -83,6 +85,22 @@ pqGetc(char *result, PGconn *conn)
} }
/*
* write 1 char to the connection
*/
int
pqPutc(char c, PGconn *conn)
{
if (pqPutBytes(&c, 1, conn) == EOF)
return EOF;
if (conn->Pfdebug)
fprintf(conn->Pfdebug, "To backend> %c\n", c);
return 0;
}
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/* pqPutBytes: local routine to write N bytes to the connection, /* pqPutBytes: local routine to write N bytes to the connection,
with buffering with buffering
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: libpq-int.h,v 1.33 2001/03/22 04:01:27 momjian Exp $ * $Id: libpq-int.h,v 1.34 2001/07/06 17:58:53 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -278,6 +278,7 @@ struct pg_conn ...@@ -278,6 +278,7 @@ struct pg_conn
PQExpBufferData workBuffer; /* expansible string */ PQExpBufferData workBuffer; /* expansible string */
int client_encoding;/* encoding id */ int client_encoding;/* encoding id */
int startup_complete;
}; };
/* String descriptions of the ExecStatusTypes. /* String descriptions of the ExecStatusTypes.
...@@ -313,6 +314,7 @@ extern void pqClearAsyncResult(PGconn *conn); ...@@ -313,6 +314,7 @@ extern void pqClearAsyncResult(PGconn *conn);
* necessarily any error. * necessarily any error.
*/ */
extern int pqGetc(char *result, 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(PQExpBuffer buf, PGconn *conn);
extern int pqPuts(const char *s, PGconn *conn); extern int pqPuts(const char *s, PGconn *conn);
extern int pqGetnchar(char *s, size_t len, PGconn *conn); extern int pqGetnchar(char *s, size_t len, PGconn *conn);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment