The attached patch implements some changes that were discussed a


			
			
				REL6_4
			
			
		
Bruce Momjian 27 years ago
parent e46df2ff6e
commit e6311b4ad0
  1. 4
      src/interfaces/libpq/fe-auth.c
  2. 116
      src/interfaces/libpq/fe-connect.c
  3. 285
      src/interfaces/libpq/fe-exec.c
  4. 16
      src/interfaces/libpq/fe-misc.c
  5. 7
      src/interfaces/libpq/fe-print.c
  6. 15
      src/interfaces/libpq/libpq-fe.h
  7. 34
      src/man/libpq.3

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.20 1998/07/20 16:57:13 momjian Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.21 1998/08/09 02:59:25 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -445,8 +445,6 @@ pg_krb5_sendauth(const char *PQerrormsg, int sock,
(void) sprintf(PQerrormsg,
"pg_krb5_sendauth: authentication rejected: \"%*s\"\n",
error->text.length, error->text.data);
fputs(PQerrormsg, stderr);
pqdebug("%s", PQerrormsg);
}
else
{

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.77 1998/07/26 04:31:36 scrappy Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.78 1998/08/09 02:59:26 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -29,7 +29,6 @@
#include <ctype.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <ctype.h> /* for isspace() */
#include "postgres.h"
@ -55,6 +54,7 @@ static void closePGconn(PGconn *conn);
static int conninfo_parse(const char *conninfo, char *errorMessage);
static char *conninfo_getval(char *keyword);
static void conninfo_free(void);
static void defaultNoticeProcessor(void * arg, const char * message);
/* XXX Why is this not static? */
void PQsetenv(PGconn *conn);
@ -181,11 +181,7 @@ PQconnectdb(const char *conninfo)
*/
conn = makeEmptyPGconn();
if (conn == NULL)
{
fprintf(stderr,
"FATAL: PQconnectdb() -- unable to allocate memory for a PGconn");
return (PGconn *) NULL;
}
/* ----------
* Parse the conninfo string and save settings in conn structure
@ -297,11 +293,7 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions, cons
conn = makeEmptyPGconn();
if (conn == NULL)
{
fprintf(stderr,
"FATAL: PQsetdbLogin() -- unable to allocate memory for a PGconn");
return (PGconn *) NULL;
}
if ((pghost == NULL) || pghost[0] == '\0')
{
@ -856,6 +848,7 @@ makeEmptyPGconn(void)
/* Zero all pointers */
MemSet((char *) conn, 0, sizeof(PGconn));
conn->noticeHook = defaultNoticeProcessor;
conn->status = CONNECTION_BAD;
conn->asyncStatus = PGASYNC_IDLE;
conn->notifyList = DLNewList();
@ -925,35 +918,20 @@ closePGconn(PGconn *conn)
if (conn->sock >= 0)
{
/*
* Try to send close message.
* If connection is already gone, that's cool. No reason for kernel
* to kill us when we try to write to it. So ignore SIGPIPE signals.
* Try to send "close connection" message to backend.
* BUT: backend might have already closed connection.
* To avoid being killed by SIGPIPE, we need to detect this before
* writing. Check for "read ready" condition which indicates EOF.
*/
#ifndef WIN32
#if defined(USE_POSIX_SIGNALS)
struct sigaction ignore_action;
struct sigaction oldaction;
ignore_action.sa_handler = SIG_IGN;
sigemptyset(&ignore_action.sa_mask);
ignore_action.sa_flags = 0;
sigaction(SIGPIPE, (struct sigaction *) & ignore_action, &oldaction);
(void) pqPuts("X", conn);
(void) pqFlush(conn);
sigaction(SIGPIPE, &oldaction, NULL);
#else
void (*oldsignal)(int);
oldsignal = signal(SIGPIPE, SIG_IGN);
(void) pqPuts("X", conn);
(void) pqFlush(conn);
signal(SIGPIPE, oldsignal);
#endif
#endif /* Win32 uses no signals at all */
while (pqReadReady(conn)) {
if (pqReadData(conn) < 0)
break;
}
if (conn->sock >= 0) {
/* Should be safe now... */
(void) pqPuts("X", conn);
(void) pqFlush(conn);
}
}
/*
@ -987,9 +965,7 @@ closePGconn(PGconn *conn)
void
PQfinish(PGconn *conn)
{
if (!conn)
fprintf(stderr, "PQfinish() -- pointer to PGconn is null\n");
else
if (conn)
{
closePGconn(conn);
freePGconn(conn);
@ -1003,9 +979,7 @@ PQfinish(PGconn *conn)
void
PQreset(PGconn *conn)
{
if (!conn)
fprintf(stderr, "PQreset() -- pointer to PGconn is null\n");
else
if (conn)
{
closePGconn(conn);
conn->status = connectDB(conn);
@ -1383,10 +1357,7 @@ char *
PQdb(PGconn *conn)
{
if (!conn)
{
fprintf(stderr, "PQdb() -- pointer to PGconn is null\n");
return (char *) NULL;
}
return conn->dbName;
}
@ -1394,10 +1365,7 @@ char *
PQuser(PGconn *conn)
{
if (!conn)
{
fprintf(stderr, "PQuser() -- pointer to PGconn is null\n");
return (char *) NULL;
}
return conn->pguser;
}
@ -1405,11 +1373,7 @@ char *
PQhost(PGconn *conn)
{
if (!conn)
{
fprintf(stderr, "PQhost() -- pointer to PGconn is null\n");
return (char *) NULL;
}
return conn->pghost;
}
@ -1417,10 +1381,7 @@ char *
PQoptions(PGconn *conn)
{
if (!conn)
{
fprintf(stderr, "PQoptions() -- pointer to PGconn is null\n");
return (char *) NULL;
}
return conn->pgoptions;
}
@ -1428,10 +1389,7 @@ char *
PQtty(PGconn *conn)
{
if (!conn)
{
fprintf(stderr, "PQtty() -- pointer to PGconn is null\n");
return (char *) NULL;
}
return conn->pgtty;
}
@ -1439,10 +1397,7 @@ char *
PQport(PGconn *conn)
{
if (!conn)
{
fprintf(stderr, "PQport() -- pointer to PGconn is null\n");
return (char *) NULL;
}
return conn->pgport;
}
@ -1450,21 +1405,16 @@ ConnStatusType
PQstatus(PGconn *conn)
{
if (!conn)
{
fprintf(stderr, "PQstatus() -- pointer to PGconn is null\n");
return CONNECTION_BAD;
}
return conn->status;
}
char *
PQerrorMessage(PGconn *conn)
{
static char noConn[] = "PQerrorMessage: conn pointer is NULL\n";
if (!conn)
{
fprintf(stderr, "PQerrorMessage() -- pointer to PGconn is null\n");
return (char *) NULL;
}
return noConn;
return conn->errorMessage;
}
@ -1472,10 +1422,7 @@ int
PQsocket(PGconn *conn)
{
if (!conn)
{
fprintf(stderr, "PQsocket() -- pointer to PGconn is null\n");
return -1;
}
return conn->sock;
}
@ -1501,3 +1448,26 @@ PQuntrace(PGconn *conn)
conn->Pfdebug = NULL;
}
}
void
PQsetNoticeProcessor (PGconn *conn, PQnoticeProcessor proc, void *arg)
{
if (conn == NULL)
return;
conn->noticeHook = proc;
conn->noticeArg = arg;
}
/*
* The default notice/error message processor just prints the
* message on stderr. Applications can override this if they
* want the messages to go elsewhere (a window, for example).
* Note that simply discarding notices is probably a bad idea.
*/
static void
defaultNoticeProcessor(void * arg, const char * message)
{
/* Note: we expect the supplied string to end with a newline already. */
fprintf(stderr, "%s", message);
}

@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.60 1998/07/14 02:41:25 momjian Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.61 1998/08/09 02:59:27 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -44,6 +44,10 @@ const char *pgresStatus[] = {
};
#define DONOTICE(conn,message) \
((*(conn)->noticeHook) ((conn)->noticeArg, (message)))
static PGresult *makeEmptyPGresult(PGconn *conn, ExecStatusType status);
static void freeTuple(PGresAttValue *tuple, int numAttributes);
static void addTuple(PGresult *res, PGresAttValue *tup);
@ -198,6 +202,14 @@ PQsendQuery(PGconn *conn, const char *query)
sprintf(conn->errorMessage, "PQsendQuery() -- query pointer is null.");
return 0;
}
/* check to see if the query string is too long */
if (strlen(query) > MAX_MESSAGE_LEN-2)
{
sprintf(conn->errorMessage, "PQsendQuery() -- query is too long. "
"Maximum length is %d\n", MAX_MESSAGE_LEN - 2);
return 0;
}
if (conn->asyncStatus != PGASYNC_IDLE)
{
sprintf(conn->errorMessage,
@ -205,20 +217,16 @@ PQsendQuery(PGconn *conn, const char *query)
return 0;
}
/* clear the error string */
conn->errorMessage[0] = '\0';
/* initialize async result-accumulation state */
conn->result = NULL;
conn->curTuple = NULL;
conn->asyncErrorMessage[0] = '\0';
/* check to see if the query string is too long */
if (strlen(query) > MAX_MESSAGE_LEN-2)
{
sprintf(conn->errorMessage, "PQsendQuery() -- query is too long. "
"Maximum length is %d\n", MAX_MESSAGE_LEN - 2);
return 0;
/* Check for pending input (asynchronous Notice or Notify messages);
* also detect the case that the backend just closed the connection.
* Note: we have to loop if the first call to pqReadData successfully
* reads some data, since in that case pqReadData won't notice whether
* the connection is now closed.
*/
while (pqReadReady(conn)) {
if (pqReadData(conn) < 0)
return 0; /* errorMessage already set */
parseInput(conn); /* deal with Notice or Notify, if any */
}
/* Don't try to send if we know there's no live connection. */
@ -229,6 +237,14 @@ PQsendQuery(PGconn *conn, const char *query)
return 0;
}
/* clear the error string */
conn->errorMessage[0] = '\0';
/* initialize async result-accumulation state */
conn->result = NULL;
conn->curTuple = NULL;
conn->asyncErrorMessage[0] = '\0';
/* send the query to the backend; */
/* the frontend-backend protocol uses 'Q' to designate queries */
if (pqPutnchar("Q", 1, conn))
@ -297,15 +313,19 @@ parseInput(PGconn *conn)
if (pqGetc(&id, conn))
return;
/*
* NOTIFY messages can happen in any state besides COPY OUT;
* NOTIFY and NOTICE messages can happen in any state besides COPY OUT;
* always process them right away.
*/
if (id == 'A')
{
/* Notify responses can happen at any time */
if (getNotify(conn))
return;
}
else if (id == 'N')
{
if (getNotice(conn))
return;
}
else
{
/*
@ -318,9 +338,10 @@ parseInput(PGconn *conn)
{
if (conn->asyncStatus == PGASYNC_IDLE)
{
fprintf(stderr,
sprintf(conn->errorMessage,
"Backend message type 0x%02x arrived while idle\n",
id);
DONOTICE(conn, conn->errorMessage);
/* Discard the unexpected message; good idea?? */
conn->inStart = conn->inEnd;
}
@ -354,8 +375,11 @@ parseInput(PGconn *conn)
if (pqGetc(&id, conn))
return;
if (id != '\0')
fprintf(stderr,
{
sprintf(conn->errorMessage,
"unexpected character %c following 'I'\n", id);
DONOTICE(conn, conn->errorMessage);
}
if (conn->result == NULL)
conn->result = makeEmptyPGresult(conn,
PGRES_EMPTY_QUERY);
@ -371,10 +395,6 @@ parseInput(PGconn *conn)
if (pqGetInt(&(conn->be_key), 4, conn))
return;
break;
case 'N': /* notices from the backend */
if (getNotice(conn))
return;
break;
case 'P': /* synchronous (normal) portal */
if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, conn))
return;
@ -408,8 +428,9 @@ parseInput(PGconn *conn)
}
else
{
fprintf(stderr,
sprintf(conn->errorMessage,
"Backend sent D message without prior T\n");
DONOTICE(conn, conn->errorMessage);
/* Discard the unexpected message; good idea?? */
conn->inStart = conn->inEnd;
return;
@ -424,8 +445,9 @@ parseInput(PGconn *conn)
}
else
{
fprintf(stderr,
sprintf(conn->errorMessage,
"Backend sent B message without prior T\n");
DONOTICE(conn, conn->errorMessage);
/* Discard the unexpected message; good idea?? */
conn->inStart = conn->inEnd;
return;
@ -783,14 +805,7 @@ getNotice(PGconn *conn)
{
if (pqGets(conn->errorMessage, ERROR_MSG_LENGTH, conn))
return EOF;
/*
* Should we really be doing this? These notices
* are not important enough for us to presume to
* put them on stderr. Maybe the caller should
* decide whether to put them on stderr or not.
* BJH 96.12.27
*/
fprintf(stderr, "%s", conn->errorMessage);
DONOTICE(conn, conn->errorMessage);
return 0;
}
@ -970,7 +985,10 @@ PQendcopy(PGconn *conn)
* To recover, reset the connection (talk about using a sledgehammer...)
*/
PQclear(result);
fprintf(stderr, "PQendcopy: resetting connection\n");
sprintf(conn->errorMessage, "PQendcopy: resetting connection\n");
DONOTICE(conn, conn->errorMessage);
PQreset(conn);
return 1;
@ -1156,11 +1174,7 @@ ExecStatusType
PQresultStatus(PGresult *res)
{
if (!res)
{
fprintf(stderr, "PQresultStatus() -- pointer to PQresult is null\n");
return PGRES_NONFATAL_ERROR;
}
return res->resultStatus;
}
@ -1168,10 +1182,7 @@ int
PQntuples(PGresult *res)
{
if (!res)
{
fprintf(stderr, "PQntuples() -- pointer to PQresult is null\n");
return 0;
}
return res->ntups;
}
@ -1179,32 +1190,64 @@ int
PQnfields(PGresult *res)
{
if (!res)
{
fprintf(stderr, "PQnfields() -- pointer to PQresult is null\n");
return 0;
}
return res->numAttributes;
}
/*
returns NULL if the field_num is invalid
*/
char *
PQfname(PGresult *res, int field_num)
* Helper routines to range-check field numbers and tuple numbers.
* Return TRUE if OK, FALSE if not
*/
static int
check_field_number(const char *routineName, PGresult *res, int field_num)
{
if (!res)
return FALSE; /* no way to display error message... */
if (field_num < 0 || field_num >= res->numAttributes)
{
fprintf(stderr, "PQfname() -- pointer to PQresult is null\n");
return NULL;
sprintf(res->conn->errorMessage,
"%s: ERROR! field number %d is out of range 0..%d\n",
routineName, field_num, res->numAttributes - 1);
DONOTICE(res->conn, res->conn->errorMessage);
return FALSE;
}
return TRUE;
}
static int
check_tuple_field_number(const char *routineName, PGresult *res,
int tup_num, int field_num)
{
if (!res)
return FALSE; /* no way to display error message... */
if (tup_num < 0 || tup_num >= res->ntups)
{
sprintf(res->conn->errorMessage,
"%s: ERROR! tuple number %d is out of range 0..%d\n",
routineName, tup_num, res->ntups - 1);
DONOTICE(res->conn, res->conn->errorMessage);
return FALSE;
}
if (field_num < 0 || field_num >= res->numAttributes)
{
fprintf(stderr,
"PQfname: ERROR! field number %d is out of range 0..%d\n",
field_num, res->numAttributes - 1);
return NULL;
sprintf(res->conn->errorMessage,
"%s: ERROR! field number %d is out of range 0..%d\n",
routineName, field_num, res->numAttributes - 1);
DONOTICE(res->conn, res->conn->errorMessage);
return FALSE;
}
return TRUE;
}
/*
returns NULL if the field_num is invalid
*/
char *
PQfname(PGresult *res, int field_num)
{
if (! check_field_number("PQfname", res, field_num))
return NULL;
if (res->attDescs)
return res->attDescs[field_num].name;
else
@ -1221,10 +1264,7 @@ PQfnumber(PGresult *res, const char *field_name)
char *field_case;
if (!res)
{
fprintf(stderr, "PQfnumber() -- pointer to PQresult is null\n");
return -1;
}
if (field_name == NULL ||
field_name[0] == '\0' ||
@ -1258,19 +1298,8 @@ PQfnumber(PGresult *res, const char *field_name)
Oid
PQftype(PGresult *res, int field_num)
{
if (!res)
{
fprintf(stderr, "PQftype() -- pointer to PQresult is null\n");
if (! check_field_number("PQftype", res, field_num))
return InvalidOid;
}
if (field_num < 0 || field_num >= res->numAttributes)
{
fprintf(stderr,
"PQftype: ERROR! field number %d is out of range 0..%d\n",
field_num, res->numAttributes - 1);
return InvalidOid;
}
if (res->attDescs)
return res->attDescs[field_num].typid;
else
@ -1280,19 +1309,8 @@ PQftype(PGresult *res, int field_num)
short
PQfsize(PGresult *res, int field_num)
{
if (!res)
{
fprintf(stderr, "PQfsize() -- pointer to PQresult is null\n");
return 0;
}
if (field_num < 0 || field_num >= res->numAttributes)
{
fprintf(stderr,
"PQfsize: ERROR! field number %d is out of range 0..%d\n",
field_num, res->numAttributes - 1);
if (! check_field_number("PQfsize", res, field_num))
return 0;
}
if (res->attDescs)
return res->attDescs[field_num].typlen;
else
@ -1302,19 +1320,8 @@ PQfsize(PGresult *res, int field_num)
int
PQfmod(PGresult *res, int field_num)
{
if (!res)
{
fprintf(stderr, "PQfmod() -- pointer to PQresult is null\n");
return 0;
}
if (field_num < 0 || field_num >= res->numAttributes)
{
fprintf(stderr,
"PQfmod: ERROR! field number %d is out of range 0..%d\n",
field_num, res->numAttributes - 1);
if (! check_field_number("PQfmod", res, field_num))
return 0;
}
if (res->attDescs)
return res->attDescs[field_num].atttypmod;
else
@ -1325,10 +1332,7 @@ char *
PQcmdStatus(PGresult *res)
{
if (!res)
{
fprintf(stderr, "PQcmdStatus() -- pointer to PQresult is null\n");
return NULL;
}
return res->cmdStatus;
}
@ -1343,10 +1347,7 @@ PQoidStatus(PGresult *res)
static char oidStatus[32] = {0};
if (!res)
{
fprintf(stderr, "PQoidStatus () -- pointer to PQresult is null\n");
return NULL;
}
return "";
oidStatus[0] = 0;
@ -1371,10 +1372,7 @@ const char *
PQcmdTuples(PGresult *res)
{
if (!res)
{
fprintf(stderr, "PQcmdTuples () -- pointer to PQresult is null\n");
return NULL;
}
return "";
if (strncmp(res->cmdStatus, "INSERT", 6) == 0 ||
strncmp(res->cmdStatus, "DELETE", 6) == 0 ||
@ -1384,9 +1382,11 @@ PQcmdTuples(PGresult *res)
if (*p == 0)
{
fprintf(stderr, "PQcmdTuples (%s) -- bad input from server\n",
sprintf(res->conn->errorMessage,
"PQcmdTuples (%s) -- bad input from server\n",
res->cmdStatus);
return NULL;
DONOTICE(res->conn, res->conn->errorMessage);
return "";
}
p++;
if (*(res->cmdStatus) != 'I') /* UPDATE/DELETE */
@ -1395,8 +1395,10 @@ PQcmdTuples(PGresult *res)
p++; /* INSERT: skip oid */
if (*p == 0)
{
fprintf(stderr, "PQcmdTuples (INSERT) -- there's no # of tuples\n");
return NULL;
sprintf(res->conn->errorMessage,
"PQcmdTuples (INSERT) -- there's no # of tuples\n");
DONOTICE(res->conn, res->conn->errorMessage);
return "";
}
p++;
return (p);
@ -1417,28 +1419,8 @@ PQcmdTuples(PGresult *res)
char *
PQgetvalue(PGresult *res, int tup_num, int field_num)
{
if (!res)
{
fprintf(stderr, "PQgetvalue: pointer to PQresult is null\n");
return NULL;
}
if (tup_num < 0 || tup_num >= res->ntups)
{
fprintf(stderr,
"PQgetvalue: There is no row %d in the query results. "
"The highest numbered row is %d.\n",
tup_num, res->ntups - 1);
if (! check_tuple_field_number("PQgetvalue", res, tup_num, field_num))
return NULL;
}
if (field_num < 0 || field_num >= res->numAttributes)
{
fprintf(stderr,
"PQgetvalue: There is no field %d in the query results. "
"The highest numbered field is %d.\n",
field_num, res->numAttributes - 1);
return NULL;
}
return res->tuples[tup_num][field_num].value;
}
@ -1450,29 +1432,8 @@ PQgetvalue(PGresult *res, int tup_num, int field_num)
int
PQgetlength(PGresult *res, int tup_num, int field_num)
{
if (!res)
{
fprintf(stderr, "PQgetlength() -- pointer to PQresult is null\n");
return 0;
}
if (tup_num < 0 || tup_num >= res->ntups)
{
fprintf(stderr,
"PQgetlength: There is no row %d in the query results. "
"The highest numbered row is %d.\n",
tup_num, res->ntups - 1);
return 0;
}
if (field_num < 0 || field_num >= res->numAttributes)
{
fprintf(stderr,
"PQgetlength: There is no field %d in the query results. "
"The highest numbered field is %d.\n",
field_num, res->numAttributes - 1);
if (! check_tuple_field_number("PQgetlength", res, tup_num, field_num))
return 0;
}
if (res->tuples[tup_num][field_num].len != NULL_LEN)
return res->tuples[tup_num][field_num].len;
else
@ -1485,28 +1446,8 @@ PQgetlength(PGresult *res, int tup_num, int field_num)
int
PQgetisnull(PGresult *res, int tup_num, int field_num)
{
if (!res)
{
fprintf(stderr, "PQgetisnull() -- pointer to PQresult is null\n");
if (! check_tuple_field_number("PQgetisnull", res, tup_num, field_num))
return 1; /* pretend it is null */
}
if (tup_num < 0 || tup_num >= res->ntups)
{
fprintf(stderr,
"PQgetisnull: There is no row %d in the query results. "
"The highest numbered row is %d.\n",
tup_num, res->ntups - 1);
return 1; /* pretend it is null */
}
if (field_num < 0 || field_num >= res->numAttributes)
{
fprintf(stderr,
"PQgetisnull: There is no field %d in the query results. "
"The highest numbered field is %d.\n",
field_num, res->numAttributes - 1);
return 1; /* pretend it is null */
}
if (res->tuples[tup_num][field_num].len == NULL_LEN)
return 1;
else

@ -24,7 +24,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.16 1998/07/03 04:24:14 momjian Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.17 1998/08/09 02:59:29 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -50,6 +50,10 @@
#include "postgres.h"
#include "libpq-fe.h"
#define DONOTICE(conn,message) \
((*(conn)->noticeHook) ((conn)->noticeArg, (message)))
/* --------------------------------------------------------------------- */
/* pqGetc:
get a character from the connection
@ -218,7 +222,9 @@ pqGetInt(int *result, int bytes, PGconn *conn)
*result = (int) ntohl(tmp4);
break;
default:
fprintf(stderr, "** int size %d not supported\n", bytes);
sprintf(conn->errorMessage,
"pqGetInt: int size %d not supported\n", bytes);
DONOTICE(conn, conn->errorMessage);
return EOF;
}
@ -252,7 +258,9 @@ pqPutInt(int value, int bytes, PGconn *conn)
return EOF;
break;
default:
fprintf(stderr, "** int size %d not supported\n", bytes);
sprintf(conn->errorMessage,
"pqPutInt: int size %d not supported\n", bytes);
DONOTICE(conn, conn->errorMessage);
return EOF;
}
@ -265,7 +273,7 @@ pqPutInt(int value, int bytes, PGconn *conn)
/* --------------------------------------------------------------------- */
/* pqReadReady: is select() saying the file is ready to read?
*/
static int
int
pqReadReady(PGconn *conn)
{
fd_set input_mask;

@ -9,7 +9,7 @@
* didn't really belong there.
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-print.c,v 1.8 1998/07/26 04:31:36 scrappy Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-print.c,v 1.9 1998/08/09 02:59:30 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -106,6 +106,7 @@ PQprint(FILE *fout,
int fs_len = strlen(po->fieldSep);
int total_line_length = 0;
int usePipe = 0;
pqsigfunc oldsigpipehandler = NULL;
char *pagerenv;
char buf[8192 * 2 + 1];
@ -193,7 +194,7 @@ PQprint(FILE *fout,
{
usePipe = 1;
#ifndef WIN32
pqsignal(SIGPIPE, SIG_IGN);
oldsigpipehandler = pqsignal(SIGPIPE, SIG_IGN);
#endif
}
else
@ -309,7 +310,7 @@ PQprint(FILE *fout,
_pclose(fout);
#else
pclose(fout);
pqsignal(SIGPIPE, SIG_DFL);
pqsignal(SIGPIPE, oldsigpipehandler);
#endif
}
if (po->html3 && !po->expanded)

@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: libpq-fe.h,v 1.36 1998/07/18 18:34:34 momjian Exp $
* $Id: libpq-fe.h,v 1.37 1998/08/09 02:59:31 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@ -121,6 +121,9 @@ extern "C"
int be_pid; /* process id of backend */
} PGnotify;
/* PQnoticeProcessor is a typedef for a callback function type */
typedef void (*PQnoticeProcessor) (void * arg, const char * message);
/* PGAsyncStatusType is private to libpq, really shouldn't be seen by users */
typedef enum
{
@ -165,6 +168,10 @@ extern "C"
/* Optional file to write trace info to */
FILE *Pfdebug;
/* Callback procedure for notice/error message processing */
PQnoticeProcessor noticeHook;
void *noticeArg;
/* Status indicators */
ConnStatusType status;
PGAsyncStatusType asyncStatus;
@ -300,6 +307,11 @@ extern "C"
extern void PQtrace(PGconn *conn, FILE *debug_port);
extern void PQuntrace(PGconn *conn);
/* Override default notice processor */
extern void PQsetNoticeProcessor (PGconn *conn,
PQnoticeProcessor proc,
void *arg);
/* === in fe-exec.c === */
/* Simple synchronous query */
extern PGresult *PQexec(PGconn *conn, const char *query);
@ -390,6 +402,7 @@ extern "C"
extern int pqGetInt(int *result, int bytes, PGconn *conn);
extern int pqPutInt(int value, int bytes, PGconn *conn);
extern int pqReadData(PGconn *conn);
extern int pqReadReady(PGconn *conn);
extern int pqFlush(PGconn *conn);
extern int pqWait(int forRead, int forWrite, PGconn *conn);

@ -1,7 +1,7 @@
.\" This is -*-nroff-*-
.\" XXX standard disclaimer belongs here....
.\" $Header: /cvsroot/pgsql/src/man/Attic/libpq.3,v 1.22 1998/07/15 17:34:06 momjian Exp $
.TH LIBPQ INTRO 07/08/98 PostgreSQL PostgreSQL
.\" $Header: /cvsroot/pgsql/src/man/Attic/libpq.3,v 1.23 1998/08/09 02:59:33 momjian Exp $
.TH LIBPQ INTRO 08/08/98 PostgreSQL PostgreSQL
.SH DESCRIPTION
Libpq is the programmer's interface to Postgres. Libpq is a set of
library routines which allows
@ -823,6 +823,36 @@ Disable tracing started by
.nf
void PQuntrace(PGconn *conn)
.fi
.PP
.SH "LIBPQ Control Functions"
.PP
.B PQsetNoticeProcessor
.IP
Control reporting of notice and warning messages generated by libpq.
.nf
void PQsetNoticeProcessor (PGconn * conn,
void (*noticeProcessor) (void * arg, const char * message),
void * arg)
.fi
By default, libpq prints "notice" messages from the backend on stderr,
as well as a few error messages that it generates by itself.
This behavior can be overridden by supplying a callback function that
does something else with the messages. The callback function is passed
the text of the error message (which includes a trailing newline), plus
a void pointer that is the same one passed to PQsetNoticeProcessor.
(This pointer can be used to access application-specific state if needed.)
The default notice processor is simply
.nf
static void
defaultNoticeProcessor(void * arg, const char * message)
{
fprintf(stderr, "%s", message);
}
.fi
To use a special notice processor, call PQsetNoticeProcessor just after
any creation of a new PGconn object.
.PP
.SH "User Authentication Functions"
.PP

Loading…
Cancel
Save