Commit e7da38bf authored by Bruce Momjian's avatar Bruce Momjian

Re-apply guc cleanup patch, with memory allocation bugs fixed.

parent 3f8db37c
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* *
* Copyright (c) 2000-2006, PostgreSQL Global Development Group * Copyright (c) 2000-2006, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/backend/utils/misc/guc-file.l,v 1.42 2006/08/12 04:12:41 momjian Exp $ * $PostgreSQL: pgsql/src/backend/utils/misc/guc-file.l,v 1.43 2006/08/13 01:30:17 momjian Exp $
*/ */
%{ %{
...@@ -50,7 +50,8 @@ int GUC_yylex(void); ...@@ -50,7 +50,8 @@ int GUC_yylex(void);
static bool ParseConfigFile(const char *config_file, const char *calling_file, static bool ParseConfigFile(const char *config_file, const char *calling_file,
int depth, GucContext context, int elevel, int depth, GucContext context, int elevel,
struct name_value_pair **head_p, struct name_value_pair **head_p,
struct name_value_pair **tail_p); struct name_value_pair **tail_p,
int *varcount);
static void free_name_value_list(struct name_value_pair * list); static void free_name_value_list(struct name_value_pair * list);
static char *GUC_scanstr(const char *s); static char *GUC_scanstr(const char *s);
...@@ -114,8 +115,10 @@ STRING \'([^'\\\n]|\\.|\'\')*\' ...@@ -114,8 +115,10 @@ STRING \'([^'\\\n]|\\.|\'\')*\'
void void
ProcessConfigFile(GucContext context) ProcessConfigFile(GucContext context)
{ {
int elevel; int elevel, i;
struct name_value_pair *item, *head, *tail; struct name_value_pair *item, *head, *tail;
bool *apply_list = NULL;
int varcount = 0;
Assert(context == PGC_POSTMASTER || context == PGC_SIGHUP); Assert(context == PGC_POSTMASTER || context == PGC_SIGHUP);
...@@ -134,25 +137,56 @@ ProcessConfigFile(GucContext context) ...@@ -134,25 +137,56 @@ ProcessConfigFile(GucContext context)
if (!ParseConfigFile(ConfigFileName, NULL, if (!ParseConfigFile(ConfigFileName, NULL,
0, context, elevel, 0, context, elevel,
&head, &tail)) &head, &tail, &varcount))
goto cleanup_list; goto cleanup_list;
/* Can we allocate memory here, what about leaving here prematurely? */
apply_list = (bool *) palloc(sizeof(bool) * varcount);
/* Check if all options are valid */ /* Check if all options are valid */
for (item = head; item; item = item->next) for (item = head, i = 0; item; item = item->next, i++)
{
bool isEqual, isContextOk;
if (!verify_config_option(item->name, item->value, context,
PGC_S_FILE, &isEqual, &isContextOk))
{ {
if (!set_config_option(item->name, item->value, context, ereport(elevel,
PGC_S_FILE, false, false)) (errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
errmsg("configuration file is invalid")));
goto cleanup_list; goto cleanup_list;
} }
/* If we got here all the options checked out okay, so apply them. */ if (isContextOk == false)
for (item = head; item; item = item->next)
{ {
apply_list[i] = false;
if (context == PGC_SIGHUP)
{
if (isEqual == false)
ereport(elevel,
(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
errmsg("parameter \"%s\" cannot be changed after server start; configuration file change ignored",
item->name)));
}
else
/* if it is boot phase, context must be valid for all
* configuration item. */
goto cleanup_list;
}
else
apply_list[i] = true;
}
/* If we got here all the options checked out okay, so apply them. */
for (item = head, i = 0; item; item = item->next, i++)
if (apply_list[i])
set_config_option(item->name, item->value, context, set_config_option(item->name, item->value, context,
PGC_S_FILE, false, true); PGC_S_FILE, false, true);
}
cleanup_list:
cleanup_list:
if (apply_list)
pfree(apply_list);
free_name_value_list(head); free_name_value_list(head);
} }
...@@ -189,7 +223,8 @@ static bool ...@@ -189,7 +223,8 @@ static bool
ParseConfigFile(const char *config_file, const char *calling_file, ParseConfigFile(const char *config_file, const char *calling_file,
int depth, GucContext context, int elevel, int depth, GucContext context, int elevel,
struct name_value_pair **head_p, struct name_value_pair **head_p,
struct name_value_pair **tail_p) struct name_value_pair **tail_p,
int *varcount)
{ {
bool OK = true; bool OK = true;
char abs_path[MAXPGPATH]; char abs_path[MAXPGPATH];
...@@ -289,7 +324,7 @@ ParseConfigFile(const char *config_file, const char *calling_file, ...@@ -289,7 +324,7 @@ ParseConfigFile(const char *config_file, const char *calling_file,
if (!ParseConfigFile(opt_value, config_file, if (!ParseConfigFile(opt_value, config_file,
depth + 1, context, elevel, depth + 1, context, elevel,
head_p, tail_p)) head_p, tail_p, varcount))
{ {
pfree(opt_name); pfree(opt_name);
pfree(opt_value); pfree(opt_value);
...@@ -333,6 +368,7 @@ ParseConfigFile(const char *config_file, const char *calling_file, ...@@ -333,6 +368,7 @@ ParseConfigFile(const char *config_file, const char *calling_file,
else else
(*tail_p)->next = item; (*tail_p)->next = item;
*tail_p = item; *tail_p = item;
(*varcount)++;
} }
/* break out of loop if read EOF, else loop for next line */ /* break out of loop if read EOF, else loop for next line */
......
This diff is collapsed.
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Copyright (c) 2000-2006, PostgreSQL Global Development Group * Copyright (c) 2000-2006, PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>. * Written by Peter Eisentraut <peter_e@gmx.net>.
* *
* $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.73 2006/08/12 04:12:41 momjian Exp $ * $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.74 2006/08/13 01:30:17 momjian Exp $
*-------------------------------------------------------------------- *--------------------------------------------------------------------
*/ */
#ifndef GUC_H #ifndef GUC_H
...@@ -193,6 +193,9 @@ extern void ParseLongOption(const char *string, char **name, char **value); ...@@ -193,6 +193,9 @@ extern void ParseLongOption(const char *string, char **name, char **value);
extern bool set_config_option(const char *name, const char *value, extern bool set_config_option(const char *name, const char *value,
GucContext context, GucSource source, GucContext context, GucSource source,
bool isLocal, bool changeVal); bool isLocal, bool changeVal);
extern bool verify_config_option(const char *name, const char *value,
GucContext context, GucSource source,
bool *isNewEqual, bool *isContextOK);
extern char *GetConfigOptionByName(const char *name, const char **varname); extern char *GetConfigOptionByName(const char *name, const char **varname);
extern void GetConfigOptionByNum(int varnum, const char **values, bool *noshow); extern void GetConfigOptionByNum(int varnum, const char **values, bool *noshow);
extern int GetNumConfigOptions(void); extern int GetNumConfigOptions(void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment