diff --git a/src/bin/pg_rewind/pg_rewind.c b/src/bin/pg_rewind/pg_rewind.c index 57a168fea2..bde90bf60b 100644 --- a/src/bin/pg_rewind/pg_rewind.c +++ b/src/bin/pg_rewind/pg_rewind.c @@ -1055,8 +1055,7 @@ static void getRestoreCommand(const char *argv0) { int rc; - char postgres_exec_path[MAXPGPATH], - cmd_output[MAXPGPATH]; + char postgres_exec_path[MAXPGPATH]; PQExpBuffer postgres_cmd; if (!restore_wal) @@ -1105,16 +1104,15 @@ getRestoreCommand(const char *argv0) /* add -C switch, for restore_command */ appendPQExpBufferStr(postgres_cmd, " -C restore_command"); - if (!pipe_read_line(postgres_cmd->data, cmd_output, sizeof(cmd_output))) - exit(1); + restore_command = pipe_read_line(postgres_cmd->data); + if (restore_command == NULL) + pg_fatal("unable to read restore_command from target cluster"); - (void) pg_strip_crlf(cmd_output); + (void) pg_strip_crlf(restore_command); - if (strcmp(cmd_output, "") == 0) + if (strcmp(restore_command, "") == 0) pg_fatal("restore_command is not set in the target cluster"); - restore_command = pg_strdup(cmd_output); - pg_log_debug("using for rewind restore_command = \'%s\'", restore_command); diff --git a/src/bin/pg_upgrade/exec.c b/src/bin/pg_upgrade/exec.c index fec8dc4c2f..3552cf00af 100644 --- a/src/bin/pg_upgrade/exec.c +++ b/src/bin/pg_upgrade/exec.c @@ -431,7 +431,7 @@ static void check_exec(const char *dir, const char *program, bool check_version) { char path[MAXPGPATH]; - char line[MAXPGPATH]; + char *line; char cmd[MAXPGPATH]; char versionstr[128]; @@ -442,7 +442,7 @@ check_exec(const char *dir, const char *program, bool check_version) snprintf(cmd, sizeof(cmd), "\"%s\" -V", path); - if (!pipe_read_line(cmd, line, sizeof(line))) + if ((line = pipe_read_line(cmd)) == NULL) pg_fatal("check for \"%s\" failed: cannot execute", path); @@ -456,4 +456,6 @@ check_exec(const char *dir, const char *program, bool check_version) pg_fatal("check for \"%s\" failed: incorrect version: found \"%s\", expected \"%s\"", path, line, versionstr); } + + pg_free(line); } diff --git a/src/common/exec.c b/src/common/exec.c index 8cfc721b12..da929f15b9 100644 --- a/src/common/exec.c +++ b/src/common/exec.c @@ -42,6 +42,8 @@ #endif #endif +#include "common/string.h" + /* Inhibit mingw CRT's auto-globbing of command line arguments */ #if defined(WIN32) && !defined(_MSC_VER) extern int _CRT_glob = 0; /* 0 turns off globbing; 1 turns it on */ @@ -328,7 +330,7 @@ find_other_exec(const char *argv0, const char *target, const char *versionstr, char *retpath) { char cmd[MAXPGPATH]; - char line[MAXPGPATH]; + char *line; if (find_my_exec(argv0, retpath) < 0) return -1; @@ -346,46 +348,55 @@ find_other_exec(const char *argv0, const char *target, snprintf(cmd, sizeof(cmd), "\"%s\" -V", retpath); - if (!pipe_read_line(cmd, line, sizeof(line))) + if ((line = pipe_read_line(cmd)) == NULL) return -1; if (strcmp(line, versionstr) != 0) + { + pfree(line); return -2; + } + pfree(line); return 0; } /* - * Execute a command in a pipe and read the first line from it. + * Execute a command in a pipe and read the first line from it. The returned + * string is palloc'd (malloc'd in frontend code), the caller is responsible + * for freeing. */ char * -pipe_read_line(char *cmd, char *line, int maxsize) +pipe_read_line(char *cmd) { - FILE *pgver; + FILE *pipe_cmd; + char *line; fflush(NULL); errno = 0; - if ((pgver = popen(cmd, "r")) == NULL) + if ((pipe_cmd = popen(cmd, "r")) == NULL) { perror("popen failure"); return NULL; } + /* Make sure popen() didn't change errno */ errno = 0; - if (fgets(line, maxsize, pgver) == NULL) + line = pg_get_line(pipe_cmd, NULL); + + if (line == NULL) { - if (feof(pgver)) - fprintf(stderr, "no data was returned by command \"%s\"\n", cmd); + if (ferror(pipe_cmd)) + log_error(errcode_for_file_access(), + _("could not read from command \"%s\": %m"), cmd); else - perror("fgets failure"); - pclose(pgver); /* no error checking */ - return NULL; + log_error(errcode_for_file_access(), + _("no data was returned by command \"%s\": %m"), cmd); } - if (pclose_check(pgver)) - return NULL; + (void) pclose_check(pipe_cmd); return line; } diff --git a/src/include/port.h b/src/include/port.h index 2e3425da63..263cf791a3 100644 --- a/src/include/port.h +++ b/src/include/port.h @@ -137,7 +137,7 @@ extern int validate_exec(const char *path); extern int find_my_exec(const char *argv0, char *retpath); extern int find_other_exec(const char *argv0, const char *target, const char *versionstr, char *retpath); -extern char *pipe_read_line(char *cmd, char *line, int maxsize); +extern char *pipe_read_line(char *cmd); /* Doesn't belong here, but this is used with find_other_exec(), so... */ #define PG_BACKEND_VERSIONSTR "postgres (PostgreSQL) " PG_VERSION "\n"