v1-0001-Move-readfile-and-free_readfile-to-file_utils.h.patch
text/x-patch
Filename: v1-0001-Move-readfile-and-free_readfile-to-file_utils.h.patch
Type: text/x-patch
Part: 0
Message:
speed up a logical replica setup
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v1-0001
Subject: Move readfile() and free_readfile() to file_utils.h
| File | + | − |
|---|---|---|
| src/bin/initdb/initdb.c | 13 | 13 |
| src/bin/pg_ctl/pg_ctl.c | 1 | 121 |
| src/common/file_utils.c | 119 | 0 |
| src/include/common/file_utils.h | 3 | 0 |
From 5827245b8a06f906f603100c8fb27be533a6c0a1 Mon Sep 17 00:00:00 2001
From: Euler Taveira <euler.taveira@enterprisedb.com>
Date: Fri, 11 Feb 2022 03:05:58 -0300
Subject: [PATCH v1 1/2] Move readfile() and free_readfile() to file_utils.h
Allow these functions to be used by other binaries.
There is a static function called readfile() in initdb.c too. Rename it
to avoid conflicting with the exposed function.
---
src/bin/initdb/initdb.c | 26 +++----
src/bin/pg_ctl/pg_ctl.c | 122 +-------------------------------
src/common/file_utils.c | 119 +++++++++++++++++++++++++++++++
src/include/common/file_utils.h | 3 +
4 files changed, 136 insertions(+), 134 deletions(-)
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 97f15971e2..a4cbfeb954 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -243,8 +243,8 @@ static char **replace_token(char **lines,
#ifndef HAVE_UNIX_SOCKETS
static char **filter_lines_with_token(char **lines, const char *token);
#endif
-static char **readfile(const char *path);
-static void writefile(char *path, char **lines);
+static char **read_text_file(const char *path);
+static void write_text_file(char *path, char **lines);
static FILE *popen_check(const char *command, const char *mode);
static char *get_id(void);
static int get_encoding_id(const char *encoding_name);
@@ -453,7 +453,7 @@ filter_lines_with_token(char **lines, const char *token)
* get the lines from a text file
*/
static char **
-readfile(const char *path)
+read_text_file(const char *path)
{
char **result;
FILE *infile;
@@ -500,7 +500,7 @@ readfile(const char *path)
* so that the resulting configuration files are nicely editable on Windows.
*/
static void
-writefile(char *path, char **lines)
+write_text_file(char *path, char **lines)
{
FILE *out_file;
char **line;
@@ -1063,7 +1063,7 @@ setup_config(void)
/* postgresql.conf */
- conflines = readfile(conf_file);
+ conflines = read_text_file(conf_file);
snprintf(repltok, sizeof(repltok), "max_connections = %d", n_connections);
conflines = replace_token(conflines, "#max_connections = 100", repltok);
@@ -1214,7 +1214,7 @@ setup_config(void)
snprintf(path, sizeof(path), "%s/postgresql.conf", pg_data);
- writefile(path, conflines);
+ write_text_file(path, conflines);
if (chmod(path, pg_file_create_mode) != 0)
{
pg_log_error("could not change permissions of \"%s\": %m", path);
@@ -1233,7 +1233,7 @@ setup_config(void)
sprintf(path, "%s/postgresql.auto.conf", pg_data);
- writefile(path, autoconflines);
+ write_text_file(path, autoconflines);
if (chmod(path, pg_file_create_mode) != 0)
{
pg_log_error("could not change permissions of \"%s\": %m", path);
@@ -1245,7 +1245,7 @@ setup_config(void)
/* pg_hba.conf */
- conflines = readfile(hba_file);
+ conflines = read_text_file(hba_file);
#ifndef HAVE_UNIX_SOCKETS
conflines = filter_lines_with_token(conflines, "@remove-line-for-nolocal@");
@@ -1319,7 +1319,7 @@ setup_config(void)
snprintf(path, sizeof(path), "%s/pg_hba.conf", pg_data);
- writefile(path, conflines);
+ write_text_file(path, conflines);
if (chmod(path, pg_file_create_mode) != 0)
{
pg_log_error("could not change permissions of \"%s\": %m", path);
@@ -1330,11 +1330,11 @@ setup_config(void)
/* pg_ident.conf */
- conflines = readfile(ident_file);
+ conflines = read_text_file(ident_file);
snprintf(path, sizeof(path), "%s/pg_ident.conf", pg_data);
- writefile(path, conflines);
+ write_text_file(path, conflines);
if (chmod(path, pg_file_create_mode) != 0)
{
pg_log_error("could not change permissions of \"%s\": %m", path);
@@ -1362,7 +1362,7 @@ bootstrap_template1(void)
printf(_("running bootstrap script ... "));
fflush(stdout);
- bki_lines = readfile(bki_file);
+ bki_lines = read_text_file(bki_file);
/* Check that bki file appears to be of the right version */
@@ -1547,7 +1547,7 @@ setup_run_file(FILE *cmdfd, const char *filename)
{
char **lines;
- lines = readfile(filename);
+ lines = read_text_file(filename);
for (char **line = lines; *line != NULL; line++)
{
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index 3c182c97d4..b87beb7380 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -26,6 +26,7 @@
#include "catalog/pg_control.h"
#include "common/controldata_utils.h"
#include "common/file_perm.h"
+#include "common/file_utils.h"
#include "common/logging.h"
#include "common/string.h"
#include "getopt_long.h"
@@ -150,8 +151,6 @@ static PTOKEN_PRIVILEGES GetPrivilegesToDelete(HANDLE hToken);
#endif
static pgpid_t get_pgpid(bool is_status_request);
-static char **readfile(const char *path, int *numlines);
-static void free_readfile(char **optlines);
static pgpid_t start_postmaster(void);
static void read_post_opts(void);
@@ -307,125 +306,6 @@ get_pgpid(bool is_status_request)
}
-/*
- * get the lines from a text file - return NULL if file can't be opened
- *
- * Trailing newlines are deleted from the lines (this is a change from pre-v10)
- *
- * *numlines is set to the number of line pointers returned; there is
- * also an additional NULL pointer after the last real line.
- */
-static char **
-readfile(const char *path, int *numlines)
-{
- int fd;
- int nlines;
- char **result;
- char *buffer;
- char *linebegin;
- int i;
- int n;
- int len;
- struct stat statbuf;
-
- *numlines = 0; /* in case of failure or empty file */
-
- /*
- * Slurp the file into memory.
- *
- * The file can change concurrently, so we read the whole file into memory
- * with a single read() call. That's not guaranteed to get an atomic
- * snapshot, but in practice, for a small file, it's close enough for the
- * current use.
- */
- fd = open(path, O_RDONLY | PG_BINARY, 0);
- 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;
- }
- buffer = pg_malloc(statbuf.st_size + 1);
-
- len = read(fd, buffer, statbuf.st_size + 1);
- close(fd);
- if (len != statbuf.st_size)
- {
- /* oops, the file size changed between fstat and read */
- free(buffer);
- return NULL;
- }
-
- /*
- * 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; i++)
- {
- if (buffer[i] == '\n')
- nlines++;
- }
-
- /* set up the result buffer */
- result = (char **) pg_malloc((nlines + 1) * sizeof(char *));
- *numlines = nlines;
-
- /* now split the buffer into lines */
- linebegin = buffer;
- n = 0;
- for (i = 0; i < len; i++)
- {
- if (buffer[i] == '\n')
- {
- int slen = &buffer[i] - linebegin;
- char *linebuf = pg_malloc(slen + 1);
-
- memcpy(linebuf, linebegin, slen);
- /* we already dropped the \n, but get rid of any \r too */
- if (slen > 0 && linebuf[slen - 1] == '\r')
- slen--;
- linebuf[slen] = '\0';
- result[n++] = linebuf;
- linebegin = &buffer[i + 1];
- }
- }
- result[n] = NULL;
-
- free(buffer);
-
- return result;
-}
-
-
-/*
- * Free memory allocated for optlines through readfile()
- */
-static void
-free_readfile(char **optlines)
-{
- char *curr_line = NULL;
- int i = 0;
-
- if (!optlines)
- return;
-
- while ((curr_line = optlines[i++]))
- free(curr_line);
-
- free(optlines);
-}
-
/*
* start/test/stop routines
*/
diff --git a/src/common/file_utils.c b/src/common/file_utils.c
index 7138068633..1f53f088c6 100644
--- a/src/common/file_utils.c
+++ b/src/common/file_utils.c
@@ -398,6 +398,125 @@ durable_rename(const char *oldfile, const char *newfile)
return 0;
}
+/*
+ * get the lines from a text file - return NULL if file can't be opened
+ *
+ * Trailing newlines are deleted from the lines (this is a change from pre-v10)
+ *
+ * *numlines is set to the number of line pointers returned; there is
+ * also an additional NULL pointer after the last real line.
+ */
+char **
+readfile(const char *path, int *numlines)
+{
+ int fd;
+ int nlines;
+ char **result;
+ char *buffer;
+ char *linebegin;
+ int i;
+ int n;
+ int len;
+ struct stat statbuf;
+
+ *numlines = 0; /* in case of failure or empty file */
+
+ /*
+ * Slurp the file into memory.
+ *
+ * The file can change concurrently, so we read the whole file into memory
+ * with a single read() call. That's not guaranteed to get an atomic
+ * snapshot, but in practice, for a small file, it's close enough for the
+ * current use.
+ */
+ fd = open(path, O_RDONLY | PG_BINARY, 0);
+ 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;
+ }
+ buffer = pg_malloc(statbuf.st_size + 1);
+
+ len = read(fd, buffer, statbuf.st_size + 1);
+ close(fd);
+ if (len != statbuf.st_size)
+ {
+ /* oops, the file size changed between fstat and read */
+ free(buffer);
+ return NULL;
+ }
+
+ /*
+ * 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; i++)
+ {
+ if (buffer[i] == '\n')
+ nlines++;
+ }
+
+ /* set up the result buffer */
+ result = (char **) pg_malloc((nlines + 1) * sizeof(char *));
+ *numlines = nlines;
+
+ /* now split the buffer into lines */
+ linebegin = buffer;
+ n = 0;
+ for (i = 0; i < len; i++)
+ {
+ if (buffer[i] == '\n')
+ {
+ int slen = &buffer[i] - linebegin;
+ char *linebuf = pg_malloc(slen + 1);
+
+ memcpy(linebuf, linebegin, slen);
+ /* we already dropped the \n, but get rid of any \r too */
+ if (slen > 0 && linebuf[slen - 1] == '\r')
+ slen--;
+ linebuf[slen] = '\0';
+ result[n++] = linebuf;
+ linebegin = &buffer[i + 1];
+ }
+ }
+ result[n] = NULL;
+
+ free(buffer);
+
+ return result;
+}
+
+
+/*
+ * Free memory allocated for optlines through readfile()
+ */
+void
+free_readfile(char **optlines)
+{
+ char *curr_line = NULL;
+ int i = 0;
+
+ if (!optlines)
+ return;
+
+ while ((curr_line = optlines[i++]))
+ free(curr_line);
+
+ free(optlines);
+}
+
#endif /* FRONTEND */
/*
diff --git a/src/include/common/file_utils.h b/src/include/common/file_utils.h
index 2811744c12..27736e3dd7 100644
--- a/src/include/common/file_utils.h
+++ b/src/include/common/file_utils.h
@@ -30,6 +30,9 @@ extern void fsync_pgdata(const char *pg_data, int serverVersion);
extern void fsync_dir_recurse(const char *dir);
extern int durable_rename(const char *oldfile, const char *newfile);
extern int fsync_parent_path(const char *fname);
+
+extern char **readfile(const char *path, int *numlines);
+extern void free_readfile(char **optlines);
#endif
extern PGFileType get_dirent_type(const char *path,
--
2.30.2