# HG changeset patch # User Vladimir Homutov # Date 1431618867 -10800 # Node ID 1b7e246e6b3836f6969f96e2f39c0238dae08c40 # Parent db138b3b645e161c5ea1c822035f87b73f628d54 Core: store and dump processed configuration. If the -T option is passed, additionally to configuration test, configuration files are output to stdout. In the debug mode, configuration files are kept in memory and can be accessed using a debugger. diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -176,9 +176,11 @@ static char **ngx_os_environ; int ngx_cdecl main(int argc, char *const *argv) { - ngx_int_t i; + ngx_buf_t *b; ngx_log_t *log; + ngx_uint_t i; ngx_cycle_t *cycle, init_cycle; + ngx_conf_dump_t *cd; ngx_core_conf_t *ccf; ngx_debug_init(); @@ -196,7 +198,7 @@ main(int argc, char *const *argv) if (ngx_show_help) { ngx_write_stderr( - "Usage: nginx [-?hvVtq] [-s signal] [-c filename] " + "Usage: nginx [-?hvVtTq] [-s signal] [-c filename] " "[-p prefix] [-g directives]" NGX_LINEFEED NGX_LINEFEED "Options:" NGX_LINEFEED @@ -205,6 +207,8 @@ main(int argc, char *const *argv) " -V : show version and configure options then exit" NGX_LINEFEED " -t : test configuration and exit" NGX_LINEFEED + " -T : test configuration, dump it and exit" + NGX_LINEFEED " -q : suppress non-error messages " "during configuration testing" NGX_LINEFEED " -s signal : send signal to a master process: " @@ -333,6 +337,23 @@ main(int argc, char *const *argv) cycle->conf_file.data); } + if (ngx_dump_config) { + cd = cycle->config_dump.elts; + + for (i = 0; i < cycle->config_dump.nelts; i++) { + + ngx_write_stdout("# configuration file "); + (void) ngx_write_fd(ngx_stdout, cd[i].name.data, + cd[i].name.len); + ngx_write_stdout(":" NGX_LINEFEED); + + b = cd[i].buffer; + + (void) ngx_write_fd(ngx_stdout, b->pos, b->last - b->pos); + ngx_write_stdout(NGX_LINEFEED); + } + } + return 0; } @@ -689,6 +710,11 @@ ngx_get_options(int argc, char *const *a ngx_test_config = 1; break; + case 'T': + ngx_test_config = 1; + ngx_dump_config = 1; + break; + case 'q': ngx_quiet_mode = 1; break; diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c --- a/src/core/ngx_conf_file.c +++ b/src/core/ngx_conf_file.c @@ -101,10 +101,13 @@ char * ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename) { char *rv; + u_char *p; + off_t size; ngx_fd_t fd; ngx_int_t rc; - ngx_buf_t buf; + ngx_buf_t buf, *tbuf; ngx_conf_file_t *prev, conf_file; + ngx_conf_dump_t *cd; enum { parse_file = 0, parse_block, @@ -158,6 +161,39 @@ ngx_conf_parse(ngx_conf_t *cf, ngx_str_t type = parse_file; + if (ngx_dump_config +#if (NGX_DEBUG) + || 1 +#endif + ) + { + p = ngx_pstrdup(cf->cycle->pool, filename); + if (p == NULL) { + goto failed; + } + + size = ngx_file_size(&cf->conf_file->file.info); + + tbuf = ngx_create_temp_buf(cf->cycle->pool, (size_t) size); + if (tbuf == NULL) { + goto failed; + } + + cd = ngx_array_push(&cf->cycle->config_dump); + if (cd == NULL) { + goto failed; + } + + cd->name.len = filename->len; + cd->name.data = p; + cd->buffer = tbuf; + + cf->conf_file->dump = tbuf; + + } else { + cf->conf_file->dump = NULL; + } + } else if (cf->conf_file->file.fd != NGX_INVALID_FILE) { type = parse_block; @@ -437,7 +473,7 @@ ngx_conf_read_token(ngx_conf_t *cf) ngx_uint_t found, need_space, last_space, sharp_comment, variable; ngx_uint_t quoted, s_quoted, d_quoted, start_line; ngx_str_t *word; - ngx_buf_t *b; + ngx_buf_t *b, *dump; found = 0; need_space = 0; @@ -450,6 +486,7 @@ ngx_conf_read_token(ngx_conf_t *cf) cf->args->nelts = 0; b = cf->conf_file->buffer; + dump = cf->conf_file->dump; start = b->pos; start_line = cf->conf_file->line; @@ -531,6 +568,10 @@ ngx_conf_read_token(ngx_conf_t *cf) b->pos = b->start + len; b->last = b->pos + n; start = b->start; + + if (dump) { + dump->last = ngx_cpymem(dump->last, b->pos, size); + } } ch = *b->pos++; diff --git a/src/core/ngx_conf_file.h b/src/core/ngx_conf_file.h --- a/src/core/ngx_conf_file.h +++ b/src/core/ngx_conf_file.h @@ -146,10 +146,17 @@ typedef struct { typedef struct { ngx_file_t file; ngx_buf_t *buffer; + ngx_buf_t *dump; ngx_uint_t line; } ngx_conf_file_t; +typedef struct { + ngx_str_t name; + ngx_buf_t *buffer; +} ngx_conf_dump_t; + + typedef char *(*ngx_conf_handler_pt)(ngx_conf_t *cf, ngx_command_t *dummy, void *conf); diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -24,6 +24,7 @@ static ngx_pool_t *ngx_temp_pool; static ngx_event_t ngx_cleaner_event; ngx_uint_t ngx_test_config; +ngx_uint_t ngx_dump_config; ngx_uint_t ngx_quiet_mode; @@ -124,6 +125,13 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) cycle->paths.pool = pool; + if (ngx_array_init(&cycle->config_dump, pool, 1, sizeof(ngx_conf_dump_t)) + != NGX_OK) + { + ngx_destroy_pool(pool); + return NULL; + } + if (old_cycle->open_files.part.nelts) { n = old_cycle->open_files.part.nelts; for (part = old_cycle->open_files.part.next; part; part = part->next) { diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h --- a/src/core/ngx_cycle.h +++ b/src/core/ngx_cycle.h @@ -52,6 +52,7 @@ struct ngx_cycle_s { ngx_array_t listening; ngx_array_t paths; + ngx_array_t config_dump; ngx_list_t open_files; ngx_list_t shared_memory; @@ -124,6 +125,7 @@ extern volatile ngx_cycle_t *ngx_cycle; extern ngx_array_t ngx_old_cycles; extern ngx_module_t ngx_core_module; extern ngx_uint_t ngx_test_config; +extern ngx_uint_t ngx_dump_config; extern ngx_uint_t ngx_quiet_mode;