3
* Scanner for the configuration file
5
* Copyright (c) 2000-2011, PostgreSQL Global Development Group
7
* src/backend/utils/misc/guc-file.l
17
#include "miscadmin.h"
18
#include "storage/fd.h"
19
#include "utils/guc.h"
22
/* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
24
#define fprintf(file, fmt, msg) ereport(ERROR, (errmsg_internal("%s", msg)))
32
GUC_UNQUOTED_STRING = 6,
38
static unsigned int ConfigFileLineno;
40
/* flex fails to supply a prototype for yylex, so provide one */
43
static char *GUC_scanstr(const char *s);
48
%option never-interactive
53
%option prefix="GUC_yy"
62
INTEGER {SIGN}?({DIGIT}+|0x{HEXDIGIT}+){UNIT_LETTER}*
64
EXPONENT [Ee]{SIGN}?{DIGIT}+
65
REAL {SIGN}?{DIGIT}*"."{DIGIT}*{EXPONENT}?
67
LETTER [A-Za-z_\200-\377]
68
LETTER_OR_DIGIT [A-Za-z_0-9\200-\377]
70
ID {LETTER}{LETTER_OR_DIGIT}*
71
QUALIFIED_ID {ID}"."{ID}
73
UNQUOTED_STRING {LETTER}({LETTER_OR_DIGIT}|[-._:/])*
74
STRING \'([^'\\\n]|\\.|\'\')*\'
78
\n ConfigFileLineno++; return GUC_EOL;
79
[ \t\r]+ /* eat whitespace */
80
#.* /* eat comment (.* matches anything until newline) */
83
{QUALIFIED_ID} return GUC_QUALIFIED_ID;
84
{STRING} return GUC_STRING;
85
{UNQUOTED_STRING} return GUC_UNQUOTED_STRING;
86
{INTEGER} return GUC_INTEGER;
87
{REAL} return GUC_REAL;
97
* Exported function to read and process the configuration file. The
98
* parameter indicates in what context the file is being read --- either
99
* postmaster startup (including standalone-backend startup) or SIGHUP.
100
* All options mentioned in the configuration file are set to new values.
101
* If an error occurs, no values will be changed.
104
ProcessConfigFile(GucContext context)
107
ConfigVariable *item,
111
struct config_string *cvc_struct;
115
Assert(context == PGC_POSTMASTER || context == PGC_SIGHUP);
117
if (context == PGC_SIGHUP)
120
* To avoid cluttering the log, only the postmaster bleats loudly
121
* about problems with the config file.
123
elevel = IsUnderPostmaster ? DEBUG2 : LOG;
128
/* Parse the file into a list of option names and values */
131
if (!ParseConfigFile(ConfigFileName, NULL, 0, elevel, &head, &tail))
135
* We need the proposed new value of custom_variable_classes to check
136
* custom variables with. ParseConfigFile ensured that if it's in
137
* the file, it's first in the list. But first check to see if we
138
* have an active value from the command line, which should override
139
* the file in any case. (Since there's no relevant env var, the
140
* only possible nondefault sources are the file and ARGV.)
142
cvc_struct = (struct config_string *)
143
find_option("custom_variable_classes", false, elevel);
145
if (cvc_struct->gen.reset_source > PGC_S_FILE)
147
cvc = guc_strdup(elevel, cvc_struct->reset_val);
151
else if (head != NULL &&
152
guc_name_compare(head->name, "custom_variable_classes") == 0)
155
* Need to canonicalize the value by calling the check hook.
159
cvc = guc_strdup(elevel, head->value);
162
if (!call_string_check_hook(cvc_struct, &cvc, &extra,
170
* Mark all extant GUC variables as not present in the config file.
171
* We need this so that we can tell below which ones have been removed
172
* from the file since we last processed it.
174
for (i = 0; i < num_guc_variables; i++)
176
struct config_generic *gconf = guc_variables[i];
178
gconf->status &= ~GUC_IS_IN_FILE;
182
* Check if all options are valid. As a side-effect, the GUC_IS_IN_FILE
183
* flag is set on each GUC variable mentioned in the list.
185
for (item = head; item; item = item->next)
187
char *sep = strchr(item->name, GUC_QUALIFIER_SEPARATOR);
192
* We have to consider three cases for custom variables:
194
* 1. The class name is not valid according to the (new) setting
195
* of custom_variable_classes. If so, reject. We don't care
196
* which side is at fault.
198
if (!is_custom_class(item->name, sep - item->name, cvc))
201
(errcode(ERRCODE_UNDEFINED_OBJECT),
202
errmsg("unrecognized configuration parameter \"%s\"",
207
* 2. There is no GUC entry. If we called set_config_option then
208
* it would make a placeholder, which we don't want to do yet,
209
* since we could still fail further down the list. Do nothing
210
* (assuming that making the placeholder will succeed later).
212
if (find_option(item->name, false, elevel) == NULL)
215
* 3. There is already a GUC entry (either real or placeholder) for
216
* the variable. In this case we should let set_config_option
217
* check it, since the assignment could well fail if it's a real
222
if (!set_config_option(item->name, item->value, context,
223
PGC_S_FILE, GUC_ACTION_SET, false))
228
* Check for variables having been removed from the config file, and
229
* revert their reset values (and perhaps also effective values) to the
230
* boot-time defaults. If such a variable can't be changed after startup,
231
* just throw a warning and continue. (This is analogous to the fact that
232
* set_config_option only throws a warning for a new but different value.
233
* If we wanted to make it a hard error, we'd need an extra pass over the
234
* list so that we could throw the error before starting to apply
237
for (i = 0; i < num_guc_variables; i++)
239
struct config_generic *gconf = guc_variables[i];
242
if (gconf->reset_source != PGC_S_FILE ||
243
(gconf->status & GUC_IS_IN_FILE))
245
if (gconf->context < PGC_SIGHUP)
248
(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
249
errmsg("parameter \"%s\" cannot be changed without restarting the server",
255
* Reset any "file" sources to "default", else set_config_option
256
* will not override those settings.
258
if (gconf->reset_source == PGC_S_FILE)
259
gconf->reset_source = PGC_S_DEFAULT;
260
if (gconf->source == PGC_S_FILE)
261
gconf->source = PGC_S_DEFAULT;
262
for (stack = gconf->stack; stack; stack = stack->prev)
264
if (stack->source == PGC_S_FILE)
265
stack->source = PGC_S_DEFAULT;
268
/* Now we can re-apply the wired-in default */
269
set_config_option(gconf->name, NULL, context, PGC_S_DEFAULT,
270
GUC_ACTION_SET, true);
271
if (context == PGC_SIGHUP)
273
(errmsg("parameter \"%s\" removed from configuration file, reset to default",
278
* Restore any variables determined by environment variables. This
279
* is a no-op except in the case where one of these had been in the
280
* config file and is now removed. PGC_S_ENV_VAR will override the
281
* wired-in default we just applied, but cannot override any other source.
283
* Keep this list in sync with InitializeGUCOptions()!
284
* PGPORT can be ignored, because it cannot be changed without restart.
285
* We assume rlimit hasn't changed, either.
287
envvar = getenv("PGDATESTYLE");
289
set_config_option("datestyle", envvar, PGC_POSTMASTER,
290
PGC_S_ENV_VAR, GUC_ACTION_SET, true);
292
envvar = getenv("PGCLIENTENCODING");
294
set_config_option("client_encoding", envvar, PGC_POSTMASTER,
295
PGC_S_ENV_VAR, GUC_ACTION_SET, true);
298
/* If we got here all the options checked out okay, so apply them. */
299
for (item = head; item; item = item->next)
301
char *pre_value = NULL;
303
/* In SIGHUP cases in the postmaster, report changes */
304
if (context == PGC_SIGHUP && !IsUnderPostmaster)
306
const char *preval = GetConfigOption(item->name, false);
308
/* string variables could be NULL; treat that as empty */
311
/* must dup, else might have dangling pointer below */
312
pre_value = pstrdup(preval);
315
if (set_config_option(item->name, item->value, context,
316
PGC_S_FILE, GUC_ACTION_SET, true))
318
set_config_sourcefile(item->name, item->filename,
323
const char *post_value = GetConfigOption(item->name, false);
327
if (strcmp(pre_value, post_value) != 0)
329
(errmsg("parameter \"%s\" changed to \"%s\"",
330
item->name, item->value)));
338
/* Remember when we last successfully loaded the config file. */
339
PgReloadTime = GetCurrentTimestamp();
342
FreeConfigVariables(head);
348
* See next function for details. This one will just work with a config_file
349
* name rather than an already opened File Descriptor
352
ParseConfigFile(const char *config_file, const char *calling_file,
353
int depth, int elevel,
354
ConfigVariable **head_p,
355
ConfigVariable **tail_p)
359
char abs_path[MAXPGPATH];
362
* Reject too-deep include nesting depth. This is just a safety check
363
* to avoid dumping core due to stack overflow if an include file loops
364
* back to itself. The maximum nesting depth is pretty arbitrary.
369
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
370
errmsg("could not open configuration file \"%s\": maximum nesting depth exceeded",
376
* If config_file is a relative path, convert to absolute. We consider
377
* it to be relative to the directory holding the calling file.
379
if (!is_absolute_path(config_file))
381
if (calling_file != NULL)
383
strlcpy(abs_path, calling_file, sizeof(abs_path));
384
get_parent_directory(abs_path);
385
join_path_components(abs_path, abs_path, config_file);
386
canonicalize_path(abs_path);
387
config_file = abs_path;
392
* calling_file is NULL, we make an absolute path from $PGDATA
394
join_path_components(abs_path, data_directory, config_file);
395
canonicalize_path(abs_path);
396
config_file = abs_path;
400
fp = AllocateFile(config_file, "r");
404
(errcode_for_file_access(),
405
errmsg("could not open configuration file \"%s\": %m",
410
OK = ParseConfigFp(fp, config_file, depth, elevel, head_p, tail_p);
418
* Read and parse a single configuration file. This function recurses
419
* to handle "include" directives.
422
* fp: file pointer from AllocateFile for the configuration file to parse
423
* config_file: absolute or relative path of file to read
424
* depth: recursion depth (used only to prevent infinite recursion)
425
* elevel: error logging level determined by ProcessConfigFile()
427
* head_p, tail_p: head and tail of linked list of name/value pairs
429
* *head_p and *tail_p must be initialized to NULL before calling the outer
430
* recursion level. On exit, they contain a list of name-value pairs read
431
* from the input file(s).
433
* Returns TRUE if successful, FALSE if an error occurred. The error has
434
* already been ereport'd, it is only necessary for the caller to clean up
435
* its own state and release the name/value pairs list.
437
* Note: if elevel >= ERROR then an error will not return control to the
438
* caller, and internal state such as open files will not be cleaned up.
439
* This case occurs only during postmaster or standalone-backend startup,
440
* where an error will lead to immediate process exit anyway; so there is
441
* no point in contorting the code so it can clean up nicely.
444
ParseConfigFp(FILE *fp, const char *config_file, int depth, int elevel,
445
ConfigVariable **head_p, ConfigVariable **tail_p)
448
YY_BUFFER_STATE lex_buffer;
454
lex_buffer = yy_create_buffer(fp, YY_BUF_SIZE);
455
yy_switch_to_buffer(lex_buffer);
457
ConfigFileLineno = 1;
459
/* This loop iterates once per logical line */
460
while ((token = yylex()))
462
char *opt_name, *opt_value;
463
ConfigVariable *item;
465
if (token == GUC_EOL) /* empty or comment line */
468
/* first token on line is option name */
469
if (token != GUC_ID && token != GUC_QUALIFIED_ID)
471
opt_name = pstrdup(yytext);
473
/* next we have an optional equal sign; discard if present */
475
if (token == GUC_EQUALS)
478
/* now we must have the option value */
479
if (token != GUC_ID &&
480
token != GUC_STRING &&
481
token != GUC_INTEGER &&
483
token != GUC_UNQUOTED_STRING)
485
if (token == GUC_STRING) /* strip quotes and escapes */
486
opt_value = GUC_scanstr(yytext);
488
opt_value = pstrdup(yytext);
490
/* now we'd like an end of line, or possibly EOF */
492
if (token != GUC_EOL)
496
/* treat EOF like \n for line numbering purposes, cf bug 4752 */
500
/* OK, process the option name and value */
501
if (guc_name_compare(opt_name, "include") == 0)
504
* An include directive isn't a variable and should be processed
507
unsigned int save_ConfigFileLineno = ConfigFileLineno;
509
if (!ParseConfigFile(opt_value, config_file,
518
yy_switch_to_buffer(lex_buffer);
519
ConfigFileLineno = save_ConfigFileLineno;
523
else if (guc_name_compare(opt_name, "custom_variable_classes") == 0)
526
* This variable must be processed first as it controls
527
* the validity of other variables; so it goes at the head
528
* of the result list. If we already found a value for it,
529
* replace with this one.
533
guc_name_compare(item->name, "custom_variable_classes") == 0)
535
/* replace existing head item */
538
item->name = opt_name;
539
item->value = opt_value;
540
item->filename = pstrdup(config_file);
541
item->sourceline = ConfigFileLineno-1;
545
/* prepend to list */
546
item = palloc(sizeof *item);
547
item->name = opt_name;
548
item->value = opt_value;
549
item->filename = pstrdup(config_file);
550
item->sourceline = ConfigFileLineno-1;
551
item->next = *head_p;
559
/* ordinary variable, append to list */
560
item = palloc(sizeof *item);
561
item->name = opt_name;
562
item->value = opt_value;
563
item->filename = pstrdup(config_file);
564
item->sourceline = ConfigFileLineno-1;
569
(*tail_p)->next = item;
573
/* break out of loop if read EOF, else loop for next line */
578
/* successful completion of parsing */
582
if (token == GUC_EOL || token == 0)
584
(errcode(ERRCODE_SYNTAX_ERROR),
585
errmsg("syntax error in file \"%s\" line %u, near end of line",
586
config_file, ConfigFileLineno - 1)));
589
(errcode(ERRCODE_SYNTAX_ERROR),
590
errmsg("syntax error in file \"%s\" line %u, near token \"%s\"",
591
config_file, ConfigFileLineno, yytext)));
595
yy_delete_buffer(lex_buffer);
601
* Free a list of ConfigVariables, including the names and the values
604
FreeConfigVariables(ConfigVariable *list)
606
ConfigVariable *item;
611
ConfigVariable *next = item->next;
615
pfree(item->filename);
625
* Strip the quotes surrounding the given string, and collapse any embedded
626
* '' sequences and backslash escapes.
628
* the string returned is palloc'd and should eventually be pfree'd by the
632
GUC_scanstr(const char *s)
639
Assert(s != NULL && s[0] == '\'');
642
Assert(s[len-1] == '\'');
644
/* Skip the leading quote; we'll handle the trailing quote below */
647
/* Since len still includes trailing quote, this is enough space */
648
newStr = palloc(len);
650
for (i = 0, j = 0; i < len; i++)
685
s[i + k] >= '0' && s[i + k] <= '7' && k < 3;
687
octVal = (octVal << 3) + (s[i + k] - '0');
689
newStr[j] = ((char) octVal);
697
else if (s[i] == '\'' && s[i+1] == '\'')
699
/* doubled quote becomes just one quote */
707
/* We copied the ending quote to newStr, so replace with \0 */
708
Assert(j > 0 && j <= len);