pgctl_paths.v01.diff
application/octet-stream
Filename: pgctl_paths.v01.diff
Type: application/octet-stream
Part: 0
Message:
fixing pg_ctl with relative paths
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: unified
Series: patch v1
| File | + | − |
|---|---|---|
| src/bin/pg_ctl/pg_ctl.c | 0 | 0 |
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
new file mode 100644
index e412d71..1aea485
*** a/src/bin/pg_ctl/pg_ctl.c
--- b/src/bin/pg_ctl/pg_ctl.c
*************** static void do_promote(void);
*** 134,139 ****
--- 134,140 ----
static void do_kill(pgpid_t pid);
static void print_msg(const char *msg);
static void adjust_data_dir(void);
+ static char *strip_datadirs(char *orig_post_opts);
#if defined(WIN32) || defined(__CYGWIN__)
static bool pgwin32_IsInstalled(SC_HANDLE);
*************** read_post_opts(void)
*** 719,724 ****
--- 720,726 ----
int len;
char *optline;
char *arg1;
+ char *orig_post_opts = NULL;
optline = optlines[0];
/* trim off line endings */
*************** read_post_opts(void)
*** 733,742 ****
{
*arg1 = '\0'; /* terminate so we get only program
* name */
! post_opts = arg1 + 1; /* point past whitespace */
}
if (exec_path == NULL)
exec_path = optline;
}
}
}
--- 735,748 ----
{
*arg1 = '\0'; /* terminate so we get only program
* name */
! orig_post_opts = arg1 + 1; /* point past whitespace */
}
if (exec_path == NULL)
exec_path = optline;
+
+ if (orig_post_opts) {
+ post_opts = strip_datadirs(orig_post_opts);
+ }
}
}
}
*************** do_start(void)
*** 819,826 ****
read_post_opts();
! /* No -D or -D already added during server start */
! if (ctl_command == RESTART_COMMAND || pgdata_opt == NULL)
pgdata_opt = "";
if (exec_path == NULL)
--- 825,831 ----
read_post_opts();
! if (pgdata_opt == NULL)
pgdata_opt = "";
if (exec_path == NULL)
*************** adjust_data_dir(void)
*** 1994,1999 ****
--- 1999,2065 ----
}
+ /*
+ * Remove any "-D" "/path/to/datadir" specifications. We don't want to
+ * preserve these during a restart, since the user will be providing
+ * a possibly-conflicting datadir which should take precedence over
+ * the old value(s). Get rid of all such datadir specifications in
+ * the string, since a user might have manually launched the postmaster
+ * with redundant specifications, e.g.
+ * postgres -D /some/dir/ -D /some/dir/ ...
+ *
+ * Note, the simple parsing here won't cope with path specifications
+ * containing embedded quotes, such as
+ * "-D" "/foo \" bar/"
+ * but such paths seem to be currently unsupported for other reasons
+ * anyway, since `pg_ctl start` / `pg_ctl stop` have inconsistent
+ * handling of such paths.
+ */
+ static char *
+ strip_datadirs(char *orig_post_opts)
+ {
+ char *datadir;
+ char *trailing_quote;
+ char *tmp = NULL;
+ char *post_opts = pg_strdup(orig_post_opts);
+
+ #define DATADIR_SPEC "\"-D\" \""
+
+ datadir = strstr(post_opts, DATADIR_SPEC);
+
+ while (datadir != NULL) {
+ trailing_quote = strchr(datadir + sizeof(DATADIR_SPEC), '"');
+ if (trailing_quote) {
+ *datadir = '\0';
+
+ /*
+ * If there are any options after the -D ...
+ * specification, preserve them by concatenating.
+ * post_opts must have enough space for strcat(),
+ * since it is the same size as post_opts, but with
+ * an '\0' inserted at *datadir.
+ */
+ if (*(trailing_quote + 1) != '\0') {
+ tmp = pg_strdup(trailing_quote + 1);
+ strcat(post_opts, tmp);
+ }
+
+ datadir = strstr(post_opts, DATADIR_SPEC);
+ }
+ else {
+ write_stderr(_("%s: unable to parse post_opts: %s"),
+ progname, orig_post_opts);
+ post_opts = orig_post_opts;
+ break;
+ }
+ }
+
+ free(tmp);
+ return post_opts;
+ }
+
+
+
int
main(int argc, char **argv)
{