Skip to content

Commit d2a5f32

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 447dad7 commit d2a5f32

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
@@ -328,10 +328,14 @@ readfile(const char *path)
328328
if (fd < 0)
329329
return NULL;
330330
if (fstat(fd, &statbuf) < 0)
331+
{
332+
close(fd);
331333
return NULL;
334+
}
332335
if (statbuf.st_size == 0)
333336
{
334337
/* empty file */
338+
close(fd);
335339
result = (char **) pg_malloc(sizeof(char *));
336340
*result = NULL;
337341
return result;
@@ -347,14 +351,17 @@ readfile(const char *path)
347351
return NULL;
348352
}
349353

350-
/* count newlines */
354+
/*
355+
* Count newlines. We expect there to be a newline after each full line,
356+
* including one at the end of file. If there isn't a newline at the end,
357+
* any characters after the last newline will be ignored.
358+
*/
351359
nlines = 0;
352-
for (i = 0; i < len - 1; i++)
360+
for (i = 0; i < len; i++)
353361
{
354362
if (buffer[i] == '\n')
355363
nlines++;
356364
}
357-
nlines++; /* account for the last line */
358365

359366
/* set up the result buffer */
360367
result = (char **) pg_malloc((nlines + 1) * sizeof(char *));
@@ -364,7 +371,7 @@ readfile(const char *path)
364371
n = 0;
365372
for (i = 0; i < len; i++)
366373
{
367-
if (buffer[i] == '\n' || i == len - 1)
374+
if (buffer[i] == '\n')
368375
{
369376
int slen = &buffer[i] - linebegin + 1;
370377
char *linebuf = pg_malloc(slen + 1);

0 commit comments

Comments
 (0)