Skip to content

Commit 95ff5b3

Browse files
committed
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.
1 parent afdc751 commit 95ff5b3

File tree

1 file changed

+11
-4
lines changed

1 file changed

+11
-4
lines changed

src/bin/pg_ctl/pg_ctl.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -320,10 +320,14 @@ readfile(const char *path)
320320
if (fd < 0)
321321
return NULL;
322322
if (fstat(fd, &statbuf) < 0)
323+
{
324+
close(fd);
323325
return NULL;
326+
}
324327
if (statbuf.st_size == 0)
325328
{
326329
/* empty file */
330+
close(fd);
327331
result = (char **) pg_malloc(sizeof(char *));
328332
*result = NULL;
329333
return result;
@@ -339,14 +343,17 @@ readfile(const char *path)
339343
return NULL;
340344
}
341345

342-
/* count newlines */
346+
/*
347+
* Count newlines. We expect there to be a newline after each full line,
348+
* including one at the end of file. If there isn't a newline at the end,
349+
* any characters after the last newline will be ignored.
350+
*/
343351
nlines = 0;
344-
for (i = 0; i < len - 1; i++)
352+
for (i = 0; i < len; i++)
345353
{
346354
if (buffer[i] == '\n')
347355
nlines++;
348356
}
349-
nlines++; /* account for the last line */
350357

351358
/* set up the result buffer */
352359
result = (char **) pg_malloc((nlines + 1) * sizeof(char *));
@@ -356,7 +363,7 @@ readfile(const char *path)
356363
n = 0;
357364
for (i = 0; i < len; i++)
358365
{
359-
if (buffer[i] == '\n' || i == len - 1)
366+
if (buffer[i] == '\n')
360367
{
361368
int slen = &buffer[i] - linebegin + 1;
362369
char *linebuf = pg_malloc(slen + 1);

0 commit comments

Comments
 (0)