aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2012-10-18 22:26:26 +0300
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2012-10-18 22:26:26 +0300
commit2a49585e2b2ee43618e9f1107e21781c5f71f6c1 (patch)
tree51a8e62cdac19749e79ac4938830d168393a32a2 /src
parent160984c8c84afb1406acd7ab71982bcae26b07fe (diff)
downloadpostgresql-2a49585e2b2ee43618e9f1107e21781c5f71f6c1.tar.gz
postgresql-2a49585e2b2ee43618e9f1107e21781c5f71f6c1.zip
Further tweaking of the readfile() function in pg_ctl.
Don't leak a file descriptor if the file is empty or we can't read its size. Expect there to be a newline at the end of the last line, too. If there isn't, ignore anything after the last newline. This makes it a tiny bit more robust in case the file is appended to concurrently, so that we don't return the last line if it hasn't been fully written yet. And this makes the code a bit less obscure, anyway. Per Tom Lane's suggestion. Backpatch to all supported branches.
Diffstat (limited to 'src')
-rw-r--r--src/bin/pg_ctl/pg_ctl.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index d550d6f1b4b..2a00cd2255d 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -338,10 +338,14 @@ readfile(const char *path)
if (fd < 0)
return NULL;
if (fstat(fd, &statbuf) < 0)
+ {
+ close(fd);
return NULL;
+ }
if (statbuf.st_size == 0)
{
/* empty file */
+ close(fd);
result = (char **) pg_malloc(sizeof(char *));
*result = NULL;
return result;
@@ -357,14 +361,17 @@ readfile(const char *path)
return NULL;
}
- /* count newlines */
+ /*
+ * Count newlines. We expect there to be a newline after each full line,
+ * including one at the end of file. If there isn't a newline at the end,
+ * any characters after the last newline will be ignored.
+ */
nlines = 0;
- for (i = 0; i < len - 1; i++)
+ for (i = 0; i < len; i++)
{
if (buffer[i] == '\n')
nlines++;
}
- nlines++; /* account for the last line */
/* set up the result buffer */
result = (char **) pg_malloc((nlines + 1) * sizeof(char *));
@@ -374,7 +381,7 @@ readfile(const char *path)
n = 0;
for (i = 0; i < len; i++)
{
- if (buffer[i] == '\n' || i == len - 1)
+ if (buffer[i] == '\n')
{
int slen = &buffer[i] - linebegin + 1;
char *linebuf = pg_malloc(slen + 1);