* Written by Peter Eisentraut
.
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.212 2004/07/01 00:51:24 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.213 2004/07/05 23:14:14 tgl Exp $
*
*--------------------------------------------------------------------
*/
gettext_noop("Sets the target for log output."),
gettext_noop("Valid values are combinations of stderr, syslog "
"and eventlog, depending on platform."),
- GUC_LIST_INPUT | GUC_REPORT
+ GUC_LIST_INPUT
},
&log_destination_string,
"stderr", assign_log_destination, NULL
static char *_ShowOption(struct config_generic * record);
+/*
+ * Some infrastructure for checking malloc/strdup/realloc calls
+ */
+static void *
+guc_malloc(int elevel, size_t size)
+{
+ void *data;
+
+ data = malloc(size);
+ if (data == NULL)
+ ereport(elevel,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of memory")));
+ return data;
+}
+
+static void *
+guc_realloc(int elevel, void *old, size_t size)
+{
+ void *data;
+
+ data = realloc(old, size);
+ if (data == NULL)
+ ereport(elevel,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of memory")));
+ return data;
+}
+
+static char *
+guc_strdup(int elevel, const char *src)
+{
+ char *data;
+
+ data = strdup(src);
+ if (data == NULL)
+ ereport(elevel,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of memory")));
+ return data;
+}
+
+
/*
* Support for assigning to a field of a string GUC item. Free the prior
* value if it's not referenced anywhere else in the item (including stacked
size_vars = num_vars + num_vars / 4;
guc_vars = (struct config_generic **)
- malloc(size_vars * sizeof(struct config_generic *));
- if (!guc_vars)
- ereport(FATAL,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("out of memory")));
+ guc_malloc(FATAL, size_vars * sizeof(struct config_generic *));
num_vars = 0;
* Add a new GUC variable to the list of known variables. The
* list is expanded if needed.
*/
-static void
-add_guc_variable(struct config_generic *var)
+static bool
+add_guc_variable(struct config_generic *var, int elevel)
{
if(num_guc_variables + 1 >= size_guc_variables)
{
- /* Increase the vector with 20%
+ /* Increase the vector by 25%
*/
int size_vars = size_guc_variables + size_guc_variables / 4;
struct config_generic** guc_vars;
if(size_vars == 0)
+ {
size_vars = 100;
-
- guc_vars = (struct config_generic**)
- malloc(size_vars * sizeof(struct config_generic*));
-
- if (guc_variables != NULL)
+ guc_vars = (struct config_generic**)
+ guc_malloc(elevel, size_vars * sizeof(struct config_generic*));
+ }
+ else
{
- memcpy(guc_vars, guc_variables,
- num_guc_variables * sizeof(struct config_generic*));
- free(guc_variables);
+ guc_vars = (struct config_generic**)
+ guc_realloc(elevel, guc_variables, size_vars * sizeof(struct config_generic*));
}
+ if(guc_vars == NULL)
+ return false; /* out of memory */
+
guc_variables = guc_vars;
size_guc_variables = size_vars;
}
guc_variables[num_guc_variables++] = var;
qsort((void*) guc_variables, num_guc_variables,
sizeof(struct config_generic*), guc_var_compare);
+ return true;
}
/*
- * Create and add a placeholder variable. Its presumed to belong
+ * Create and add a placeholder variable. It's presumed to belong
* to a valid custom variable class at this point.
*/
static struct config_string*
-add_placeholder_variable(const char *name)
+add_placeholder_variable(const char *name, int elevel)
{
size_t sz = sizeof(struct config_string) + sizeof(char*);
- struct config_string* var = (struct config_string*)malloc(sz);
- struct config_generic* gen = &var->gen;
+ struct config_string* var;
+ struct config_generic* gen;
+ var = (struct config_string*)guc_malloc(elevel, sz);
+ if(var == NULL)
+ return NULL;
+
+ gen = &var->gen;
memset(var, 0, sz);
- gen->name = strdup(name);
+ gen->name = guc_strdup(elevel, name);
+ if(gen->name == NULL)
+ {
+ free(var);
+ return NULL;
+ }
+
gen->context = PGC_USERSET;
gen->group = CUSTOM_OPTIONS;
gen->short_desc = "GUC placeholder variable";
* no 'static' place to point to.
*/
var->variable = (char**)(var + 1);
- add_guc_variable((struct config_generic*)var);
+
+ if(!add_guc_variable((struct config_generic*) var, elevel))
+ {
+ free((void *) gen->name);
+ free(var);
+ return NULL;
+ }
+
return var;
}
* else return NULL.
*/
static struct config_generic *
-find_option(const char *name)
+find_option(const char *name, int elevel)
{
const char *dot;
const char **key = &name;
for (i = 0; map_old_guc_names[i] != NULL; i += 2)
{
if (guc_name_compare(name, map_old_guc_names[i]) == 0)
- return find_option(map_old_guc_names[i+1]);
+ return find_option(map_old_guc_names[i+1], elevel);
}
/*
dot = strchr(name, GUC_QUALIFIER_SEPARATOR);
if(dot != NULL && is_custom_class(name, dot - name))
/* Add a placeholder variable for this name */
- return (struct config_generic*)add_placeholder_variable(name);
+ return (struct config_generic*)add_placeholder_variable(name, elevel);
/* Unknown name */
return NULL;
break;
}
- str = strdup(conf->boot_val);
- if (str == NULL)
- ereport(FATAL,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("out of memory")));
+ str = guc_strdup(FATAL, conf->boot_val);
conf->reset_val = str;
if (conf->assign_hook)
else
elevel = ERROR;
- record = find_option(name);
+ record = find_option(name, elevel);
if (record == NULL)
{
ereport(elevel,
if (value)
{
- newval = strdup(value);
+ newval = guc_strdup(elevel, value);
if (newval == NULL)
- {
- ereport(elevel,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("out of memory")));
return false;
- }
if (record->context == PGC_USERLIMIT)
{
* make this case work the same as the normal
* assignment case.
*/
- newval = strdup(conf->reset_val);
+ newval = guc_strdup(elevel, conf->reset_val);
if (newval == NULL)
- {
- ereport(elevel,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("out of memory")));
return false;
- }
source = conf->gen.reset_source;
}
else
struct config_generic *record;
static char buffer[256];
- record = find_option(name);
+ record = find_option(name, ERROR);
if (record == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
struct config_generic *record;
static char buffer[256];
- record = find_option(name);
+ record = find_option(name, ERROR);
if (record == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
return NULL;
/* Else get flags for the variable */
- record = find_option(name);
+ record = find_option(name, ERROR);
if (record == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
if(res == NULL)
{
- add_guc_variable(variable);
+ add_guc_variable(variable, ERROR);
return;
}
GucContext context,
enum config_type type)
{
- gen->name = strdup(name);
+ gen->name = guc_strdup(ERROR, name);
gen->context = context;
gen->group = CUSTOM_OPTIONS;
gen->short_desc = short_desc;
GucShowHook show_hook)
{
size_t sz = sizeof(struct config_bool);
- struct config_bool* var = (struct config_bool*)malloc(sz);
+ struct config_bool* var = (struct config_bool*)guc_malloc(ERROR, sz);
memset(var, 0, sz);
init_custom_variable(&var->gen, name, short_desc, long_desc, context, PGC_BOOL);
GucShowHook show_hook)
{
size_t sz = sizeof(struct config_int);
- struct config_int* var = (struct config_int*)malloc(sz);
+ struct config_int* var = (struct config_int*)guc_malloc(ERROR, sz);
memset(var, 0, sz);
init_custom_variable(&var->gen, name, short_desc, long_desc, context, PGC_INT);
GucShowHook show_hook)
{
size_t sz = sizeof(struct config_real);
- struct config_real* var = (struct config_real*)malloc(sz);
+ struct config_real* var = (struct config_real*)guc_malloc(ERROR, sz);
memset(var, 0, sz);
init_custom_variable(&var->gen, name, short_desc, long_desc, context, PGC_REAL);
GucShowHook show_hook)
{
size_t sz = sizeof(struct config_string);
- struct config_string* var = (struct config_string*)malloc(sz);
+ struct config_string* var = (struct config_string*)guc_malloc(ERROR, sz);
memset(var, 0, sz);
init_custom_variable(&var->gen, name, short_desc, long_desc, context, PGC_STRING);
{
struct config_generic *record;
- record = find_option(name);
+ record = find_option(name, ERROR);
if (record == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
/*
* Open file
*/
- new_filename = malloc(strlen(DataDir) + strlen(CONFIG_EXEC_PARAMS) +
+ new_filename = guc_malloc(elevel, strlen(DataDir) + strlen(CONFIG_EXEC_PARAMS) +
strlen(".new") + 2);
- filename = malloc(strlen(DataDir) + strlen(CONFIG_EXEC_PARAMS) + 2);
- if (new_filename == NULL || filename == NULL)
+ if(new_filename == NULL)
+ return;
+
+ filename = guc_malloc(elevel, strlen(DataDir) + strlen(CONFIG_EXEC_PARAMS) + 2);
+ if (filename == NULL)
{
- ereport(elevel,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("out of memory")));
+ free(new_filename);
return;
}
+
sprintf(new_filename, "%s/" CONFIG_EXEC_PARAMS ".new", DataDir);
sprintf(filename, "%s/" CONFIG_EXEC_PARAMS, DataDir);
elog(FATAL, "invalid format of exec config params file");
}
if (i == 0)
- str = malloc(maxlen);
+ str = guc_malloc(FATAL, maxlen);
else if (i == maxlen)
- str = realloc(str, maxlen *= 2);
+ str = guc_realloc(FATAL, str, maxlen *= 2);
str[i++] = ch;
} while (ch != 0);
/*
* Open file
*/
- filename = malloc(strlen(DataDir) + strlen(CONFIG_EXEC_PARAMS) + 2);
- if (filename == NULL)
- {
- ereport(ERROR,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("out of memory")));
- return;
- }
+ filename = guc_malloc(FATAL, strlen(DataDir) + strlen(CONFIG_EXEC_PARAMS) + 2);
sprintf(filename, "%s/" CONFIG_EXEC_PARAMS, DataDir);
fp = AllocateFile(filename, "r");
if ((varname = read_string_with_null(fp)) == NULL)
break;
- if ((record = find_option(varname)) == NULL)
+ if ((record = find_option(varname, FATAL)) == NULL)
elog(FATAL, "failed to locate variable %s in exec config params file",varname);
if ((varvalue = read_string_with_null(fp)) == NULL)
elog(FATAL, "invalid format of exec config params file");
if (string[equal_pos] == '=')
{
- *name = malloc(equal_pos + 1);
- if (!*name)
- ereport(FATAL,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("out of memory")));
+ *name = guc_malloc(FATAL, equal_pos + 1);
strncpy(*name, string, equal_pos);
(*name)[equal_pos] = '\0';
- *value = strdup(&string[equal_pos + 1]);
- if (!*value)
- ereport(FATAL,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("out of memory")));
+ *value = guc_strdup(FATAL, &string[equal_pos + 1]);
}
else
{
/* no equal sign in string */
- *name = strdup(string);
- if (!*name)
- ereport(FATAL,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("out of memory")));
+ *name = guc_strdup(FATAL, string);
*value = NULL;
}