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'.
This commit is contained in:
parent
9981b0f9ef
commit
e77aaade34
src/interfaces/libpq
@ -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
|
|||||||
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)
|
|||||||
freePGconn(conn);
|
freePGconn(conn);
|
||||||
conn = NULL;
|
conn = NULL;
|
||||||
}
|
}
|
||||||
|
conn->startup_complete = FALSE;
|
||||||
return conn;
|
return 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)
|
|||||||
* 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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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)
|
|||||||
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)
|
|||||||
* 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)
|
|||||||
/*
|
/*
|
||||||
* 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,
|
|||||||
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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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 @@
|
|||||||
#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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 @@
|
|||||||
* 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
|
|||||||
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);
|
|||||||
* 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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user