From: Igor <igor@sba.miami.edu>
Subject: [PATCHES] More psql and libpq patches Well..these would be the last patches until the release (I hope)... I ran the regression tests while watching psql under purify, and it did not leak even one byte. In this patch: * Plugged a major leak when PSQL reads files for input (either through \i options or through -f option) * Fixed the one remaining leak in PSQL in not clearing PGresult *results everywhere it is supposed to. (Thanks Tymm) * Fixed A small leak in PSQL not clearing all the PGsettings correctly. * A not-so-obvious (but small) leak in Libpq when PQsetdb fails for any reason. * Added \n to some Libpq error messages to make them easier to digest.. * Finally, added /* PURIFY */ comment to some of the code indicating the reason for why it was added/changed...for future developers.
This commit is contained in:
parent
442306fe36
commit
8d1f52ef24
|
@ -7,7 +7,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.70 1997/06/03 06:17:34 vadim Exp $
|
* $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.71 1997/06/06 01:41:24 scrappy Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -184,7 +184,8 @@ slashUsage(PsqlSettings * ps)
|
||||||
static PGresult *
|
static PGresult *
|
||||||
PSQLexec(PsqlSettings * ps, char *query)
|
PSQLexec(PsqlSettings * ps, char *query)
|
||||||
{
|
{
|
||||||
PGresult *res = PQexec(ps->db, query);
|
PGresult *res;
|
||||||
|
res = PQexec(ps->db, query);
|
||||||
if (!res)
|
if (!res)
|
||||||
fputs(PQerrorMessage(ps->db), stderr);
|
fputs(PQerrorMessage(ps->db), stderr);
|
||||||
else {
|
else {
|
||||||
|
@ -259,7 +260,6 @@ tableList(PsqlSettings * ps, bool deep_tablelist, char table_index_both)
|
||||||
strcat(listbuf, " ORDER BY relname ");
|
strcat(listbuf, " ORDER BY relname ");
|
||||||
if (!(res = PSQLexec(ps, listbuf)))
|
if (!(res = PSQLexec(ps, listbuf)))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* first, print out the attribute names */
|
/* first, print out the attribute names */
|
||||||
nColumns = PQntuples(res);
|
nColumns = PQntuples(res);
|
||||||
if (nColumns > 0) {
|
if (nColumns > 0) {
|
||||||
|
@ -278,7 +278,7 @@ tableList(PsqlSettings * ps, bool deep_tablelist, char table_index_both)
|
||||||
strcpy(table[i], PQgetvalue(res, i, 1));
|
strcpy(table[i], PQgetvalue(res, i, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
PQclear(res);
|
PQclear(res); /* PURIFY */
|
||||||
for (i = 0; i < nColumns; i++) {
|
for (i = 0; i < nColumns; i++) {
|
||||||
tableDesc(ps, table[i]);
|
tableDesc(ps, table[i]);
|
||||||
}
|
}
|
||||||
|
@ -309,6 +309,7 @@ tableList(PsqlSettings * ps, bool deep_tablelist, char table_index_both)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
PQclear(res); /* PURIFY */
|
||||||
switch (table_index_both) {
|
switch (table_index_both) {
|
||||||
case 't': fprintf(stderr, "Couldn't find any tables!\n");
|
case 't': fprintf(stderr, "Couldn't find any tables!\n");
|
||||||
break;
|
break;
|
||||||
|
@ -507,7 +508,10 @@ gets_fromFile(char *prompt, FILE * source)
|
||||||
|
|
||||||
/* read up to MAX_QUERY_BUFFER characters */
|
/* read up to MAX_QUERY_BUFFER characters */
|
||||||
if (fgets(line, MAX_QUERY_BUFFER, source) == NULL)
|
if (fgets(line, MAX_QUERY_BUFFER, source) == NULL)
|
||||||
|
{
|
||||||
|
free(line);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
line[MAX_QUERY_BUFFER - 1] = '\0';
|
line[MAX_QUERY_BUFFER - 1] = '\0';
|
||||||
len = strlen(line);
|
len = strlen(line);
|
||||||
|
@ -579,17 +583,14 @@ SendQuery(bool * success_p, PsqlSettings * settings, const char *query,
|
||||||
&(settings->opt));
|
&(settings->opt));
|
||||||
fflush(settings->queryFout);
|
fflush(settings->queryFout);
|
||||||
}
|
}
|
||||||
PQclear(results);
|
|
||||||
break;
|
break;
|
||||||
case PGRES_EMPTY_QUERY:
|
case PGRES_EMPTY_QUERY:
|
||||||
*success_p = true;
|
*success_p = true;
|
||||||
PQclear(results);
|
|
||||||
break;
|
break;
|
||||||
case PGRES_COMMAND_OK:
|
case PGRES_COMMAND_OK:
|
||||||
*success_p = true;
|
*success_p = true;
|
||||||
if (!settings->quiet)
|
if (!settings->quiet)
|
||||||
fprintf(stdout, "%s\n", PQcmdStatus(results));
|
fprintf(stdout, "%s\n", PQcmdStatus(results));
|
||||||
PQclear(results);
|
|
||||||
break;
|
break;
|
||||||
case PGRES_COPY_OUT:
|
case PGRES_COPY_OUT:
|
||||||
*success_p = true;
|
*success_p = true;
|
||||||
|
@ -601,7 +602,6 @@ SendQuery(bool * success_p, PsqlSettings * settings, const char *query,
|
||||||
|
|
||||||
handleCopyOut(results, settings->quiet, stdout);
|
handleCopyOut(results, settings->quiet, stdout);
|
||||||
}
|
}
|
||||||
PQclear(results);
|
|
||||||
break;
|
break;
|
||||||
case PGRES_COPY_IN:
|
case PGRES_COPY_IN:
|
||||||
*success_p = true;
|
*success_p = true;
|
||||||
|
@ -609,7 +609,6 @@ SendQuery(bool * success_p, PsqlSettings * settings, const char *query,
|
||||||
handleCopyIn(results, false, copystream);
|
handleCopyIn(results, false, copystream);
|
||||||
else
|
else
|
||||||
handleCopyIn(results, !settings->quiet, stdin);
|
handleCopyIn(results, !settings->quiet, stdin);
|
||||||
PQclear(results);
|
|
||||||
break;
|
break;
|
||||||
case PGRES_NONFATAL_ERROR:
|
case PGRES_NONFATAL_ERROR:
|
||||||
case PGRES_FATAL_ERROR:
|
case PGRES_FATAL_ERROR:
|
||||||
|
@ -634,6 +633,7 @@ SendQuery(bool * success_p, PsqlSettings * settings, const char *query,
|
||||||
notify->relname, notify->be_pid);
|
notify->relname, notify->be_pid);
|
||||||
free(notify);
|
free(notify);
|
||||||
}
|
}
|
||||||
|
if(results) PQclear(results);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1434,7 +1434,6 @@ MainLoop(PsqlSettings * settings, FILE * source)
|
||||||
}
|
}
|
||||||
|
|
||||||
query_start = line;
|
query_start = line;
|
||||||
|
|
||||||
if (line == NULL) { /* No more input. Time to quit */
|
if (line == NULL) { /* No more input. Time to quit */
|
||||||
if (!settings->quiet)
|
if (!settings->quiet)
|
||||||
printf("EOF\n"); /* Goes on prompt line */
|
printf("EOF\n"); /* Goes on prompt line */
|
||||||
|
@ -1544,8 +1543,10 @@ MainLoop(PsqlSettings * settings, FILE * source)
|
||||||
fprintf(stderr, "query buffer max length of %d exceeded\n",
|
fprintf(stderr, "query buffer max length of %d exceeded\n",
|
||||||
MAX_QUERY_BUFFER);
|
MAX_QUERY_BUFFER);
|
||||||
fprintf(stderr, "query line ignored\n");
|
fprintf(stderr, "query line ignored\n");
|
||||||
|
free (line);
|
||||||
} else {
|
} else {
|
||||||
if (query_start[0] != '\0') {
|
if (query_start[0] != '\0') {
|
||||||
|
|
||||||
querySent = false;
|
querySent = false;
|
||||||
if (query[0] != '\0') {
|
if (query[0] != '\0') {
|
||||||
strcat(query, "\n");
|
strcat(query, "\n");
|
||||||
|
@ -1553,6 +1554,7 @@ MainLoop(PsqlSettings * settings, FILE * source)
|
||||||
} else
|
} else
|
||||||
strcpy(query, query_start);
|
strcpy(query, query_start);
|
||||||
}
|
}
|
||||||
|
free(line); /* PURIFY */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slashCmdStatus == 0) {
|
if (slashCmdStatus == 0) {
|
||||||
|
@ -1560,7 +1562,6 @@ MainLoop(PsqlSettings * settings, FILE * source)
|
||||||
successResult &= success;
|
successResult &= success;
|
||||||
querySent = true;
|
querySent = true;
|
||||||
}
|
}
|
||||||
free(line); /* free storage malloc'd by GetNextLine */
|
|
||||||
}
|
}
|
||||||
} /* while */
|
} /* while */
|
||||||
return successResult;
|
return successResult;
|
||||||
|
@ -1702,6 +1703,7 @@ main(int argc, char **argv)
|
||||||
if (PQstatus(settings.db) == CONNECTION_BAD) {
|
if (PQstatus(settings.db) == CONNECTION_BAD) {
|
||||||
fprintf(stderr, "Connection to database '%s' failed.\n", dbname);
|
fprintf(stderr, "Connection to database '%s' failed.\n", dbname);
|
||||||
fprintf(stderr, "%s", PQerrorMessage(settings.db));
|
fprintf(stderr, "%s", PQerrorMessage(settings.db));
|
||||||
|
PQfinish(settings.db);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (listDatabases) {
|
if (listDatabases) {
|
||||||
|
@ -1731,6 +1733,8 @@ main(int argc, char **argv)
|
||||||
sprintf(line, "\\i %s", qfilename);
|
sprintf(line, "\\i %s", qfilename);
|
||||||
}
|
}
|
||||||
HandleSlashCmds(&settings, line, "");
|
HandleSlashCmds(&settings, line, "");
|
||||||
|
if (!singleSlashCmd) free (line); /* PURIFY */
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (singleQuery) {
|
if (singleQuery) {
|
||||||
bool success; /* The query succeeded at the backend */
|
bool success; /* The query succeeded at the backend */
|
||||||
|
@ -1741,6 +1745,8 @@ main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
PQfinish(settings.db);
|
PQfinish(settings.db);
|
||||||
|
free(settings.opt.fieldSep); /* PURIFY */
|
||||||
|
if(settings.prompt) free(settings.prompt); /* PURIFY */
|
||||||
|
|
||||||
return !successResult;
|
return !successResult;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.36 1997/06/01 15:38:52 scrappy Exp $
|
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.37 1997/06/06 01:42:02 scrappy Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -569,6 +569,12 @@ connectDB(PGconn *conn)
|
||||||
return CONNECTION_OK;
|
return CONNECTION_OK;
|
||||||
|
|
||||||
connect_errReturn:
|
connect_errReturn:
|
||||||
|
|
||||||
|
/* Igor/6/3/97 - We need to free it here...otherwise the function
|
||||||
|
returns without setting conn->port to port. Because of that
|
||||||
|
any way of referencing this variable will be lost and it's allocated
|
||||||
|
memory will not be freed. */
|
||||||
|
free(port); /* PURIFY */
|
||||||
return CONNECTION_BAD;
|
return CONNECTION_BAD;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -581,6 +587,7 @@ connect_errReturn:
|
||||||
static void
|
static void
|
||||||
freePGconn(PGconn *conn)
|
freePGconn(PGconn *conn)
|
||||||
{
|
{
|
||||||
|
if (!conn) return;
|
||||||
if (conn->pghost) free(conn->pghost);
|
if (conn->pghost) free(conn->pghost);
|
||||||
if (conn->pgtty) free(conn->pgtty);
|
if (conn->pgtty) free(conn->pgtty);
|
||||||
if (conn->pgoptions) free(conn->pgoptions);
|
if (conn->pgoptions) free(conn->pgoptions);
|
||||||
|
@ -639,7 +646,7 @@ void
|
||||||
PQfinish(PGconn *conn)
|
PQfinish(PGconn *conn)
|
||||||
{
|
{
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
fprintf(stderr,"PQfinish() -- pointer to PGconn is null");
|
fprintf(stderr,"PQfinish() -- pointer to PGconn is null\n");
|
||||||
} else {
|
} else {
|
||||||
if (conn->status == CONNECTION_OK)
|
if (conn->status == CONNECTION_OK)
|
||||||
closePGconn(conn);
|
closePGconn(conn);
|
||||||
|
@ -655,7 +662,7 @@ void
|
||||||
PQreset(PGconn *conn)
|
PQreset(PGconn *conn)
|
||||||
{
|
{
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
fprintf(stderr,"PQreset() -- pointer to PGconn is null");
|
fprintf(stderr,"PQreset() -- pointer to PGconn is null\n");
|
||||||
} else {
|
} else {
|
||||||
closePGconn(conn);
|
closePGconn(conn);
|
||||||
conn->status = connectDB(conn);
|
conn->status = connectDB(conn);
|
||||||
|
@ -957,7 +964,7 @@ char*
|
||||||
PQdb(PGconn* conn)
|
PQdb(PGconn* conn)
|
||||||
{
|
{
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
fprintf(stderr,"PQdb() -- pointer to PGconn is null");
|
fprintf(stderr,"PQdb() -- pointer to PGconn is null\n");
|
||||||
return (char *)NULL;
|
return (char *)NULL;
|
||||||
}
|
}
|
||||||
return conn->dbName;
|
return conn->dbName;
|
||||||
|
@ -967,7 +974,7 @@ char*
|
||||||
PQuser(PGconn* conn)
|
PQuser(PGconn* conn)
|
||||||
{
|
{
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
fprintf(stderr,"PQuser() -- pointer to PGconn is null");
|
fprintf(stderr,"PQuser() -- pointer to PGconn is null\n");
|
||||||
return (char *)NULL;
|
return (char *)NULL;
|
||||||
}
|
}
|
||||||
return conn->pguser;
|
return conn->pguser;
|
||||||
|
@ -977,7 +984,7 @@ char*
|
||||||
PQhost(PGconn* conn)
|
PQhost(PGconn* conn)
|
||||||
{
|
{
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
fprintf(stderr,"PQhost() -- pointer to PGconn is null");
|
fprintf(stderr,"PQhost() -- pointer to PGconn is null\n");
|
||||||
return (char *)NULL;
|
return (char *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -988,7 +995,7 @@ char*
|
||||||
PQoptions(PGconn* conn)
|
PQoptions(PGconn* conn)
|
||||||
{
|
{
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
fprintf(stderr,"PQoptions() -- pointer to PGconn is null");
|
fprintf(stderr,"PQoptions() -- pointer to PGconn is null\n");
|
||||||
return (char *)NULL;
|
return (char *)NULL;
|
||||||
}
|
}
|
||||||
return conn->pgoptions;
|
return conn->pgoptions;
|
||||||
|
@ -998,7 +1005,7 @@ char*
|
||||||
PQtty(PGconn* conn)
|
PQtty(PGconn* conn)
|
||||||
{
|
{
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
fprintf(stderr,"PQtty() -- pointer to PGconn is null");
|
fprintf(stderr,"PQtty() -- pointer to PGconn is null\n");
|
||||||
return (char *)NULL;
|
return (char *)NULL;
|
||||||
}
|
}
|
||||||
return conn->pgtty;
|
return conn->pgtty;
|
||||||
|
@ -1008,7 +1015,7 @@ char*
|
||||||
PQport(PGconn* conn)
|
PQport(PGconn* conn)
|
||||||
{
|
{
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
fprintf(stderr,"PQport() -- pointer to PGconn is null");
|
fprintf(stderr,"PQport() -- pointer to PGconn is null\n");
|
||||||
return (char *)NULL;
|
return (char *)NULL;
|
||||||
}
|
}
|
||||||
return conn->pgport;
|
return conn->pgport;
|
||||||
|
@ -1018,7 +1025,7 @@ ConnStatusType
|
||||||
PQstatus(PGconn* conn)
|
PQstatus(PGconn* conn)
|
||||||
{
|
{
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
fprintf(stderr,"PQstatus() -- pointer to PGconn is null");
|
fprintf(stderr,"PQstatus() -- pointer to PGconn is null\n");
|
||||||
return CONNECTION_BAD;
|
return CONNECTION_BAD;
|
||||||
}
|
}
|
||||||
return conn->status;
|
return conn->status;
|
||||||
|
@ -1028,7 +1035,7 @@ char*
|
||||||
PQerrorMessage(PGconn* conn)
|
PQerrorMessage(PGconn* conn)
|
||||||
{
|
{
|
||||||
if (!conn) {
|
if (!conn) {
|
||||||
fprintf(stderr,"PQerrorMessage() -- pointer to PGconn is null");
|
fprintf(stderr,"PQerrorMessage() -- pointer to PGconn is null\n");
|
||||||
return (char *)NULL;
|
return (char *)NULL;
|
||||||
}
|
}
|
||||||
return conn->errorMessage;
|
return conn->errorMessage;
|
||||||
|
|
Loading…
Reference in New Issue