306
307
readfile(const char *path)
316
if ((infile = fopen(path, "r")) == NULL)
319
/* pass over the file twice - the first time to size the result */
321
while ((c = fgetc(infile)) != EOF)
320
* Slurp the file into memory.
322
* The file can change concurrently, so we read the whole file into memory
323
* with a single read() call. That's not guaranteed to get an atomic
324
* snapshot, but in practice, for a small file, it's close enough for the
327
fd = open(path, O_RDONLY | PG_BINARY, 0);
330
if (fstat(fd, &statbuf) < 0)
335
if (statbuf.st_size == 0)
339
result = (char **) pg_malloc(sizeof(char *));
343
buffer = pg_malloc(statbuf.st_size + 1);
345
len = read(fd, buffer, statbuf.st_size + 1);
347
if (len != statbuf.st_size)
349
/* oops, the file size changed between fstat and read */
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.
360
for (i = 0; i < len; i++)
362
if (buffer[i] == '\n')
327
if (linelen > maxlength)
333
/* handle last line without a terminating newline (yuck) */
336
if (linelen > maxlength)
339
/* set up the result and the line buffer */
366
/* set up the result buffer */
340
367
result = (char **) pg_malloc((nlines + 1) * sizeof(char *));
341
buffer = (char *) pg_malloc(maxlength + 1);
343
/* now reprocess the file and store the lines */
346
while (fgets(buffer, maxlength + 1, infile) != NULL)
347
result[nlines++] = xstrdup(buffer);
369
/* now split the buffer into lines */
372
for (i = 0; i < len; i++)
374
if (buffer[i] == '\n')
376
int slen = &buffer[i] - linebegin + 1;
377
char *linebuf = pg_malloc(slen + 1);
378
memcpy(linebuf, linebegin, slen);
379
linebuf[slen] = '\0';
380
result[n++] = linebuf;
381
linebegin = &buffer[i + 1];
351
result[nlines] = NULL;