mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-27 08:39:28 +08:00
Fix mistakes in pg_ctl's code for "start -w" that tries to cope with
non-default settings for the postmaster's port number. The code to parse command line options and postgresql.conf entries wasn't quite right about whitespace or quotes, and it was coded in a not-very-readable way too. Per bug #3969 from Itagaki Takahiro, though this is more extensive than his proposed patch (which fixed only the whitespace problem). This code has been broken since it was put in in 8.0, so patch all the way back.
This commit is contained in:
parent
5ce6829b73
commit
7454515e12
@ -4,7 +4,7 @@
|
||||
*
|
||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/bin/pg_ctl/pg_ctl.c,v 1.92 2008/01/01 19:45:55 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/bin/pg_ctl/pg_ctl.c,v 1.93 2008/02/20 22:18:15 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -49,8 +49,6 @@ int optreset;
|
||||
typedef long pgpid_t;
|
||||
|
||||
|
||||
#define WHITESPACE "\f\n\r\t\v" /* as defined by isspace() */
|
||||
|
||||
/* postgres version ident string */
|
||||
#define PM_VERSIONSTR "postgres (PostgreSQL) " PG_VERSION "\n"
|
||||
|
||||
@ -416,33 +414,52 @@ test_postmaster_connection(bool do_checkpoint)
|
||||
int i;
|
||||
char portstr[32];
|
||||
char *p;
|
||||
char *q;
|
||||
char connstr[128]; /* Should be way more than enough! */
|
||||
|
||||
*portstr = '\0';
|
||||
|
||||
/* post_opts */
|
||||
/*
|
||||
* Look in post_opts for a -p switch.
|
||||
*
|
||||
* This parsing code is not amazingly bright; it could for instance
|
||||
* get fooled if ' -p' occurs within a quoted argument value. Given
|
||||
* that few people pass complicated settings in post_opts, it's
|
||||
* probably good enough.
|
||||
*/
|
||||
for (p = post_opts; *p;)
|
||||
{
|
||||
/* advance past whitespace/quoting */
|
||||
while (isspace((unsigned char) *p) || *p == '\'' || *p == '"')
|
||||
/* advance past whitespace */
|
||||
while (isspace((unsigned char) *p))
|
||||
p++;
|
||||
|
||||
if (strncmp(p, "-p", strlen("-p")) == 0)
|
||||
if (strncmp(p, "-p", 2) == 0)
|
||||
{
|
||||
p += strlen("-p");
|
||||
/* advance past whitespace/quoting */
|
||||
p += 2;
|
||||
/* advance past any whitespace/quoting */
|
||||
while (isspace((unsigned char) *p) || *p == '\'' || *p == '"')
|
||||
p++;
|
||||
strlcpy(portstr, p, Min(strcspn(p, "\"'" WHITESPACE) + 1,
|
||||
sizeof(portstr)));
|
||||
/* find end of value (not including any ending quote!) */
|
||||
q = p;
|
||||
while (*q &&
|
||||
!(isspace((unsigned char) *q) || *q == '\'' || *q == '"'))
|
||||
q++;
|
||||
/* and save the argument value */
|
||||
strlcpy(portstr, p, Min((q - p) + 1, sizeof(portstr)));
|
||||
/* keep looking, maybe there is another -p */
|
||||
p = q;
|
||||
}
|
||||
/* Advance to next whitespace */
|
||||
while (*p && !isspace((unsigned char) *p))
|
||||
p++;
|
||||
}
|
||||
|
||||
/* config file */
|
||||
/*
|
||||
* Search config file for a 'port' option.
|
||||
*
|
||||
* This parsing code isn't amazingly bright either, but it should be
|
||||
* okay for valid port settings.
|
||||
*/
|
||||
if (!*portstr)
|
||||
{
|
||||
char **optlines;
|
||||
@ -456,28 +473,35 @@ test_postmaster_connection(bool do_checkpoint)
|
||||
|
||||
while (isspace((unsigned char) *p))
|
||||
p++;
|
||||
if (strncmp(p, "port", strlen("port")) != 0)
|
||||
if (strncmp(p, "port", 4) != 0)
|
||||
continue;
|
||||
p += strlen("port");
|
||||
p += 4;
|
||||
while (isspace((unsigned char) *p))
|
||||
p++;
|
||||
if (*p != '=')
|
||||
continue;
|
||||
p++;
|
||||
while (isspace((unsigned char) *p))
|
||||
/* advance past any whitespace/quoting */
|
||||
while (isspace((unsigned char) *p) || *p == '\'' || *p == '"')
|
||||
p++;
|
||||
strlcpy(portstr, p, Min(strcspn(p, "#" WHITESPACE) + 1,
|
||||
sizeof(portstr)));
|
||||
/* find end of value (not including any ending quote/comment!) */
|
||||
q = p;
|
||||
while (*q &&
|
||||
!(isspace((unsigned char) *q) ||
|
||||
*q == '\'' || *q == '"' || *q == '#'))
|
||||
q++;
|
||||
/* and save the argument value */
|
||||
strlcpy(portstr, p, Min((q - p) + 1, sizeof(portstr)));
|
||||
/* keep looking, maybe there is another */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* environment */
|
||||
/* Check environment */
|
||||
if (!*portstr && getenv("PGPORT") != NULL)
|
||||
strlcpy(portstr, getenv("PGPORT"), sizeof(portstr));
|
||||
|
||||
/* default */
|
||||
/* Else use compiled-in default */
|
||||
if (!*portstr)
|
||||
snprintf(portstr, sizeof(portstr), "%d", DEF_PGPORT);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user