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();
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
" -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: "
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;
}
ngx_test_config = 1;
break;
+ case 'T':
+ ngx_test_config = 1;
+ ngx_dump_config = 1;
+ break;
+
case 'q':
ngx_quiet_mode = 1;
break;
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,
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;
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;
cf->args->nelts = 0;
b = cf->conf_file->buffer;
+ dump = cf->conf_file->dump;
start = b->pos;
start_line = cf->conf_file->line;
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++;
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);
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;
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) {
ngx_array_t listening;
ngx_array_t paths;
+ ngx_array_t config_dump;
ngx_list_t open_files;
ngx_list_t shared_memory;
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;