mirror of
https://github.com/postgres/postgres.git
synced 2025-07-12 21:01:52 +03:00
From: Igor <igor@sba.miami.edu>
Subject: [PATCHES] memory leak patches in libpq and psql A couple of small memory leak patches (detected with Purify) primarily in libpq. * Fixed (NULL) border problem in psql (run psql, do \m, then select something from a table...row separators will be nulls) * Fixed memory leak with the abovementioned border not being freed properly. * Fixed memory leak in freePGconn() not freeing conn->port * Fixed up PQclear() to free parts of PGresult only if these parts are not null. * Fixed a decent memory leak that occured after executing every command in psql. PGresult *results was not freed most of the time. There is still a leak being detected (2 bytes) in readline functions, but I think this is old readline library. I will install new one and test it.
This commit is contained in:
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.66 1997/05/24 14:38:05 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.67 1997/06/01 15:38:42 scrappy Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -612,6 +612,7 @@ SendQuery(bool * success_p, PsqlSettings * settings, const char *query,
|
|||||||
notify->relname, notify->be_pid);
|
notify->relname, notify->be_pid);
|
||||||
free(notify);
|
free(notify);
|
||||||
}
|
}
|
||||||
|
PQclear(results);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.35 1997/05/20 03:38:49 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.36 1997/06/01 15:38:52 scrappy Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -588,6 +588,7 @@ freePGconn(PGconn *conn)
|
|||||||
if (conn->dbName) free(conn->dbName);
|
if (conn->dbName) free(conn->dbName);
|
||||||
if (conn->pguser) free(conn->pguser);
|
if (conn->pguser) free(conn->pguser);
|
||||||
if (conn->notifyList) DLFreeList(conn->notifyList);
|
if (conn->notifyList) DLFreeList(conn->notifyList);
|
||||||
|
if (conn->port) free(conn->port);
|
||||||
free(conn);
|
free(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.31 1997/06/01 04:59:25 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.32 1997/06/01 15:39:08 scrappy Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -58,6 +58,9 @@ static void addTuple(PGresult *res, PGresAttValue *tup);
|
|||||||
static PGresAttValue* getTuple(PGconn *conn, PGresult *res, int binary);
|
static PGresAttValue* getTuple(PGconn *conn, PGresult *res, int binary);
|
||||||
static PGresult* makeEmptyPGresult(PGconn *conn, ExecStatusType status);
|
static PGresult* makeEmptyPGresult(PGconn *conn, ExecStatusType status);
|
||||||
static void fill(int length, int max, char filler, FILE *fp);
|
static void fill(int length, int max, char filler, FILE *fp);
|
||||||
|
static char* do_header(FILE *fout, PQprintOpt *po, const int nFields,
|
||||||
|
int fieldMax[], char *fieldNames[], unsigned char fieldNotNum[],
|
||||||
|
const int fs_len, PGresult *res);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PQclear -
|
* PQclear -
|
||||||
@ -78,16 +81,16 @@ PQclear(PGresult* res)
|
|||||||
if (res->tuples[i][j].value)
|
if (res->tuples[i][j].value)
|
||||||
free(res->tuples[i][j].value);
|
free(res->tuples[i][j].value);
|
||||||
}
|
}
|
||||||
free(res->tuples[i]);
|
if (res->tuples[i]) free(res->tuples[i]);
|
||||||
}
|
}
|
||||||
free(res->tuples);
|
if (res->tuples) free(res->tuples);
|
||||||
|
|
||||||
/* free all the attributes */
|
/* free all the attributes */
|
||||||
for (i=0;i<res->numAttributes;i++) {
|
for (i=0;i<res->numAttributes;i++) {
|
||||||
if (res->attDescs[i].name)
|
if (res->attDescs[i].name)
|
||||||
free(res->attDescs[i].name);
|
free(res->attDescs[i].name);
|
||||||
}
|
}
|
||||||
free(res->attDescs);
|
if (res->attDescs) free(res->attDescs);
|
||||||
|
|
||||||
/* free the structure itself */
|
/* free the structure itself */
|
||||||
free(res);
|
free(res);
|
||||||
@ -590,8 +593,6 @@ PQexec(PGconn* conn, const char* query)
|
|||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PQnotifies
|
* PQnotifies
|
||||||
* returns a PGnotify* structure of the latest async notification
|
* returns a PGnotify* structure of the latest async notification
|
||||||
@ -663,7 +664,6 @@ PQgetline(PGconn *conn, char *s, int maxlen)
|
|||||||
return(1); /* returning a full buffer */
|
return(1); /* returning a full buffer */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PQputline -- sends a string to the backend.
|
* PQputline -- sends a string to the backend.
|
||||||
*
|
*
|
||||||
@ -734,7 +734,6 @@ fill (int length, int max, char filler, FILE *fp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PQdisplayTuples()
|
* PQdisplayTuples()
|
||||||
* kept for backward compatibility
|
* kept for backward compatibility
|
||||||
@ -973,12 +972,13 @@ do_field(PQprintOpt *po, PGresult *res,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static char*
|
||||||
do_header(FILE *fout, PQprintOpt *po, const int nFields, int fieldMax[],
|
do_header(FILE *fout, PQprintOpt *po, const int nFields, int fieldMax[],
|
||||||
char *fieldNames[], unsigned char fieldNotNum[],
|
char *fieldNames[], unsigned char fieldNotNum[],
|
||||||
const int fs_len, char *border, PGresult *res) {
|
const int fs_len, PGresult *res) {
|
||||||
|
|
||||||
int j; /* for loop index */
|
int j; /* for loop index */
|
||||||
|
char *border=NULL;
|
||||||
|
|
||||||
if (po->html3)
|
if (po->html3)
|
||||||
fputs("<tr>", fout);
|
fputs("<tr>", fout);
|
||||||
@ -986,15 +986,17 @@ do_header(FILE *fout, PQprintOpt *po, const int nFields, int fieldMax[],
|
|||||||
int j; /* for loop index */
|
int j; /* for loop index */
|
||||||
int tot=0;
|
int tot=0;
|
||||||
int n=0;
|
int n=0;
|
||||||
char *p;
|
char *p=NULL;
|
||||||
for (; n < nFields; n++)
|
for (; n < nFields; n++)
|
||||||
tot+=fieldMax[n]+fs_len+(po->standard? 2: 0);
|
tot+=fieldMax[n]+fs_len+(po->standard? 2: 0);
|
||||||
if (po->standard)
|
if (po->standard)
|
||||||
tot+=fs_len*2+2;
|
tot+=fs_len*2+2;
|
||||||
if (!(p=border=malloc(tot+1))) {
|
border=malloc(tot+1);
|
||||||
|
if (!border) {
|
||||||
perror("malloc");
|
perror("malloc");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
p=border;
|
||||||
if (po->standard) {
|
if (po->standard) {
|
||||||
char *fs=po->fieldSep;
|
char *fs=po->fieldSep;
|
||||||
while (*fs++)
|
while (*fs++)
|
||||||
@ -1038,6 +1040,7 @@ do_header(FILE *fout, PQprintOpt *po, const int nFields, int fieldMax[],
|
|||||||
fputs("</tr>\n", fout);
|
fputs("</tr>\n", fout);
|
||||||
else
|
else
|
||||||
fprintf(fout, "\n%s\n", border);
|
fprintf(fout, "\n%s\n", border);
|
||||||
|
return border;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1262,12 +1265,14 @@ PQprint(FILE *fout,
|
|||||||
fprintf(fout, "<table %s>", po->tableOpt? po->tableOpt: "");
|
fprintf(fout, "<table %s>", po->tableOpt? po->tableOpt: "");
|
||||||
}
|
}
|
||||||
if (po->header)
|
if (po->header)
|
||||||
do_header(fout, po, nFields, fieldMax, fieldNames, fieldNotNum,
|
border = do_header(fout, po, nFields, fieldMax, fieldNames,
|
||||||
fs_len, border, res);
|
fieldNotNum, fs_len, res);
|
||||||
for (i = 0; i < nTups; i++)
|
for (i = 0; i < nTups; i++)
|
||||||
output_row(fout, po, nFields, fields,
|
output_row(fout, po, nFields, fields,
|
||||||
fieldNotNum, fieldMax, border, i);
|
fieldNotNum, fieldMax, border, i);
|
||||||
free(fields);
|
free(fields);
|
||||||
|
if (border)
|
||||||
|
free(border);
|
||||||
}
|
}
|
||||||
if (po->header && !po->html3)
|
if (po->header && !po->html3)
|
||||||
fprintf (fout, "(%d row%s)\n\n",PQntuples(res),
|
fprintf (fout, "(%d row%s)\n\n",PQntuples(res),
|
||||||
@ -1279,8 +1284,6 @@ PQprint(FILE *fout,
|
|||||||
pclose(fout);
|
pclose(fout);
|
||||||
pqsignal(SIGPIPE, SIG_DFL);
|
pqsignal(SIGPIPE, SIG_DFL);
|
||||||
}
|
}
|
||||||
if (border)
|
|
||||||
free(border);
|
|
||||||
if (po->html3 && !po->expanded)
|
if (po->html3 && !po->expanded)
|
||||||
fputs("</table>\n", fout);
|
fputs("</table>\n", fout);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user