コード例 #1
0
ngx_shm_zone_t * 
ngx_http_get_shm_zone(ngx_str_t *shm_name_t) {
	
	ngx_shm_zone_t 		**zone;
    size_t 				i;
    zone = g_shm_dict_list->elts;

    if (g_shm_dict_list == NULL || zone == NULL) {
    	return NULL;
    }

	for (i = 0; i < g_shm_dict_list->nelts; i++) {
	
		if( shm_name_t->len == 0 && i == 0) {

			ngx_log_error(NGX_LOG_DEBUG, ((ngx_shm_dict_ctx_t *)(zone[i]->data))->log, 0,
			                    "[ah_shm_zone] process=[%d] get_shm_zone default name is  %V \n",
			                    ngx_getpid(),&zone[i]->shm.name);

			return zone[i];
		}
        
		if ( ngx_strcmp(shm_name_t->data, zone[i]->shm.name.data) == 0) {

			ngx_log_error(NGX_LOG_DEBUG, ((ngx_shm_dict_ctx_t *)(zone[i]->data))->log, 0,
			                    "[ah_shm_zone] process=[%d] get_shm_zone name is  %V \n",
			                    ngx_getpid(),shm_name_t);

            return zone[i];
		}
    }
	
	return NULL;
}
コード例 #2
0
ファイル: test_impl.cpp プロジェクト: cy1ng/nginx-tcp-server
/**
 * 上下文初始化
 */
int TestContext::ctx_init(ngx_cycle_t* cycle)
{
	test_config_t* cfg = &this->m_config;
	this->m_cycle = cycle;
	this->m_mysql_pool = mysql_pool_new(cfg->mysql_config.conns, &cfg->mysql_config);
	NLOG_INFO("[%d] mysql_pool: %p", ngx_getpid(), this->m_mysql_pool);
	#define SQL_CREATE_TBL "drop table if exists ngx_test; "\
				"create table ngx_test(`key` varchar(32) primary key,value int default 0); "\
				"insert into ngx_test values('testkey', 0);"
	int ret = 0;
	MYSQL* mysql = this->mysql_get();
	if(mysql == NULL){
		NLOG_ERROR("get mysql connection failed!");
		ret = ERRNO_SYSTEM;
		return ret; 
	}
	NLOG_INFO("init ngx_test table!");
	ret = mysql_queryex(mysql, SQL_CREATE_TBL);
	NLOG_INFO("init ngx_test table ret:%d", ret);
	if(ret == 0){ 
		mysql_free_all_result(mysql);
	}else{ 
		NLOG_ERROR("init table failed!ret:%d, sql:[%s]", ret, SQL_CREATE_TBL);
		ret = ERRNO_SYSTEM;
	}
	// 在Init中取得的链接必须关闭掉,因为这个链接不是非阻塞的。
	this->mysql_close(mysql);

	return NGX_OK;  

}
コード例 #3
0
ファイル: ngx_daemon.c プロジェクト: UnrealPawn/nginx
ngx_int_t
ngx_daemon(ngx_log_t *log)
{
    int  fd;

    switch (fork()) {
    case -1:
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "fork() failed");
        return NGX_ERROR;

    case 0:
        break;

    default:
        exit(0);
    }

    ngx_parent = ngx_pid;
    ngx_pid = ngx_getpid();

    if (setsid() == -1) {
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "setsid() failed");
        return NGX_ERROR;
    }

    umask(0);

    fd = open("/dev/null", O_RDWR);
    if (fd == -1) {
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
                      "open(\"/dev/null\") failed");
        return NGX_ERROR;
    }

    if (dup2(fd, STDIN_FILENO) == -1) {
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDIN) failed");
        return NGX_ERROR;
    }

    if (dup2(fd, STDOUT_FILENO) == -1) {
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDOUT) failed");
        return NGX_ERROR;
    }

#if 0
    if (dup2(fd, STDERR_FILENO) == -1) {
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDERR) failed");
        return NGX_ERROR;
    }
#endif

    if (fd > STDERR_FILENO) {
        if (close(fd) == -1) {
            ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "close() failed");
            return NGX_ERROR;
        }
    }

    return NGX_OK;
}
コード例 #4
0
/*创建守护进程,具体创建方法可以参考《unix环境高级编程》*/
ngx_int_t ngx_daemon(ngx_log_t *log)
{
    int  fd;

    switch (fork()) {
    case -1:
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "fork() failed");
        return NGX_ERROR;

    case 0:          //子进程作为守护进程
        break;

    default:
        exit(0);  //父进程退出
    }

    ngx_pid = ngx_getpid();

    if (setsid() == -1) {   //setsid创建一个新会话
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "setsid() failed");
        return NGX_ERROR;
    }

    umask(0);

    //打开文件/dev/null,使得其拥有守护进程的0,1,2。这样防止守护进程在终端设备上显示输出
    fd = open("/dev/null", O_RDWR);
    if (fd == -1) {
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
                      "open(\"/dev/null\") failed");
        return NGX_ERROR;
    }

    if (dup2(fd, STDIN_FILENO) == -1) {
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDIN) failed");
        return NGX_ERROR;
    }

    if (dup2(fd, STDOUT_FILENO) == -1) {
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDOUT) failed");
        return NGX_ERROR;
    }

#if 0
    if (dup2(fd, STDERR_FILENO) == -1) {
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDERR) failed");
        return NGX_ERROR;
    }
#endif

    if (fd > STDERR_FILENO) {
        if (close(fd) == -1) {  //关闭不需要的文件描述符
            ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "close() failed");
            return NGX_ERROR;
        }
    }

    return NGX_OK;
}
コード例 #5
0
ファイル: shmtest_mod.c プロジェクト: hexiay/ngx_shmap
ngx_int_t  ngx_http_shmtest_init_process(ngx_cycle_t *cycle)
{
	shmtest_main_conf_t* conf =  (shmtest_main_conf_t*)ngx_get_conf(cycle->conf_ctx, ngx_http_shmtest_module);
	if(conf == NULL){
		NLOG_INFO("conf is null!");
		return 0;
	}

	printf("process [%d] inited!\n", ngx_getpid());
	//多进程并发测试
	int i;
	int64_t ret=0;
	for(i=0;i<10000;i++){
		ngx_str_t key = ngx_string("test");
		ngx_shmap_inc_int(conf->shmap, &key, 1, 0, &ret);
	}
	printf("process [%d] init ok! ret=%lld\n", ngx_getpid(), (long long)ret);

	return 0;
}
static ngx_int_t
worker_process_write_out_stats(u_char *name, size_t len, void *val, void *para1, void *para2)
{
    ngx_uint_t   i;
    ngx_http_accounting_stats_t  *stats;

    char output_buffer[1024];

    ngx_uint_t status_code_buckets[10];
    ngx_memzero(status_code_buckets, sizeof(status_code_buckets));

    stats = (ngx_http_accounting_stats_t *)val;

    if (stats->nr_requests > 0) {
        for (i = 0; i < http_status_code_count; i++) {
            if (index_to_http_status_code_map[i] == NGX_HTTP_CLIENT_CLOSED_REQUEST) {
                status_code_buckets[9] += stats->http_status_code[i];
            } else {
                ngx_uint_t bucket_idx = index_to_http_status_code_map[i] / 100;
                status_code_buckets[bucket_idx] += stats->http_status_code[i];    
            }
            stats->http_status_code[i] = 0;
        }
    } else {
        // no requests, let's not emit any stats!
        return NGX_OK;
    }

    sprintf(output_buffer, "%i|%ld|%ld|%s|%ld|%ld|%ld|%lu|%lu|%lu|%lu|%lu|%lu",
                ngx_getpid(),
                ngx_http_accounting_old_time,
                ngx_http_accounting_new_time,
                name,
                stats->nr_requests,
                stats->bytes_in,
                stats->bytes_out,
                stats->total_latency_ms / (stats->nr_requests > 0 ? stats->nr_requests : 1),
                stats->upstream_total_latency_ms / (stats->nr_requests > 0 ? stats->nr_requests : 1),
                status_code_buckets[2],
                status_code_buckets[4],
                status_code_buckets[5],
                status_code_buckets[9]
            );

    stats->nr_requests = 0;
    stats->bytes_out = 0;
    stats->bytes_in = 0;
    stats->total_latency_ms = 0;
    stats->upstream_total_latency_ms = 0;

    syslog(LOG_INFO, "%s", output_buffer);

    return NGX_OK;
}
ngx_int_t
ngx_http_accounting_worker_process_init(ngx_cycle_t *cycle)
{
    ngx_int_t rc;
    ngx_time_t  *time;
    ngx_http_accounting_main_conf_t *amcf;

    amcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_accounting_module);

    if (!amcf->enable) {
        return NGX_OK;
    }

    init_http_status_code_map();

    time = ngx_timeofday();

    ngx_http_accounting_old_time = time->sec;
    ngx_http_accounting_new_time = time->sec;

    openlog((char *)ngx_http_accounting_title, LOG_NDELAY, LOG_SYSLOG);
    syslog(LOG_INFO, "pid:%i|Process:init", ngx_getpid());

    rc = ngx_http_accounting_hash_init(&stats_hash, NGX_HTTP_ACCOUNTING_NR_BUCKETS, cycle->pool);
    if (rc != NGX_OK) {
        return rc;
    }

    ngx_memzero(&write_out_ev, sizeof(ngx_event_t));

    write_out_ev.data = NULL;
    write_out_ev.log = cycle->log;
    write_out_ev.handler = worker_process_alarm_handler;

    srand(ngx_getpid());
    ngx_add_timer(&write_out_ev, WORKER_PROCESS_TIMER_INTERVAL*(1000-rand()%200));

    return NGX_OK;
}
void ngx_http_accounting_worker_process_exit(ngx_cycle_t *cycle)
{
    ngx_http_accounting_main_conf_t *amcf;

    amcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_accounting_module);

    if (!amcf->enable) {
        return;
    }

    worker_process_alarm_handler(NULL);

    syslog(LOG_INFO, "pid:%i|Process:exit", ngx_getpid());
}
コード例 #9
0
ファイル: ngx_daemon.c プロジェクト: lingjf/nginx_analyse
ngx_int_t ngx_daemon(ngx_log_t *log)
{
   int fd;

   switch (fork()) {
   case -1:
      printf("fork() failed");
      return NGX_ERROR;

   case 0: /* child process */
      break;

   default: /* parent process*/
      exit(0);
   }

   ngx_pid = ngx_getpid();

   if (setsid() == -1) {
      printf("setsid() failed");
      return NGX_ERROR;
   }

   umask(0);

   fd = open("/dev/null", O_RDWR);
   if (fd == -1) {
      printf("open(\"/dev/null\") failed");
      return NGX_ERROR;
   }

   if (dup2(fd, STDIN_FILENO) == -1) {
      printf("dup2(STDIN) failed");
      return NGX_ERROR;
   }

   if (dup2(fd, STDOUT_FILENO) == -1) {
      printf("dup2(STDOUT) failed");
      return NGX_ERROR;
   }

   if (fd > STDERR_FILENO) {
      if (close(fd) == -1) {
         printf("close() failed");
         return NGX_ERROR;
      }
   }

   return NGX_OK;
}
static ngx_int_t
worker_process_write_out_stats(u_char *name, size_t len, void *val, void *para1, void *para2)
{
    ngx_uint_t   i;
    ngx_http_accounting_stats_t  *stats;

    char temp_buffer[128];
    char output_buffer[1024];

    stats = (ngx_http_accounting_stats_t *)val;

    if (stats->nr_requests == 0) {
        return NGX_OK;
    }

    sprintf(output_buffer, "pid:%i|from:%ld|to:%ld|accounting_id:%s|requests:%ld|bytes_in:%ld|bytes_out:%ld|latency_ms:%lu|upstream_latency_ms:%lu",
                ngx_getpid(),
                ngx_http_accounting_old_time,
                ngx_http_accounting_new_time,
                name,
                stats->nr_requests,
                stats->bytes_in,
                stats->bytes_out,
                stats->total_latency_ms,
                stats->total_upstream_latency_ms
            );

    stats->nr_requests = 0;
    stats->bytes_in = 0;
    stats->bytes_out = 0;
    stats->total_latency_ms = 0;
    stats->total_upstream_latency_ms = 0;

    for (i = 0; i < http_status_code_count; i++) {
        if(stats->http_status_code[i] > 0) {
            sprintf(temp_buffer, "|%ld:%ld",
                        index_to_http_status_code_map[i],
                        stats->http_status_code[i]);

            strcat(output_buffer, temp_buffer);

            stats->http_status_code[i] = 0;
        }
    }

    syslog(LOG_INFO, "%s", output_buffer);

    return NGX_OK;
}
コード例 #11
0
int
ngx_shm_dict_handler_delete(ngx_shm_zone_t* zone_t, ngx_str_t *key) {
	
	int 					rc;
	ngx_shm_dict_ctx_t   	*ctx;
	ctx = zone_t->data;

	rc = ngx_shm_dict_delete(zone_t,key);
	
	ngx_log_error(NGX_LOG_DEBUG, ctx->log, 0,
	            "[ah_shm_zone] process=[%d] operator=[%s] zone=[%V] key=[%V] "
	            "rc=[%d]\n",ngx_getpid(),"del",&zone_t->shm.name,key,rc);

	return rc;
}
コード例 #12
0
int
ngx_shm_dict_handler_flush_all(ngx_shm_zone_t* zone_t) {
	
	int 					rc;
	ngx_shm_dict_ctx_t   	*ctx;
	ctx = zone_t->data;

	rc = ngx_shm_dict_flush_all(zone_t);
	
	ngx_log_error(NGX_LOG_DEBUG, ctx->log, 0,
	            "[ah_shm_zone] process=[%d] operator=[%s] zone=[%V] rc=[%d]\n",
	            ngx_getpid(),"flush",&zone_t->shm.name,rc);


	return rc;
}
コード例 #13
0
int ngx_shm_dict_handler_set_exptime(ngx_shm_zone_t* zone_t, ngx_str_t* key,
		uint32_t exptime) {

	int 					rc;
	ngx_shm_dict_ctx_t   	*ctx;
	ctx = zone_t->data;

	rc = ngx_shm_dict_set_exptime(zone_t, key,exptime);

	ngx_log_error(NGX_LOG_DEBUG, ctx->log, 0,
	            "[ah_shm_zone] process=[%d] operator=[%s] zone=[%V] key=[%V] "
	            "exptime=[%d] rc=[%d]\n",ngx_getpid(),"set",
	            &zone_t->shm.name,key,exptime,rc);
	
	return rc;
}
コード例 #14
0
static void
ngx_error_signal_handler(int signo)
{
    void                 *buffer;
    size_t                size;
    ngx_log_t            *log;
    ngx_signal_t         *sig;
    struct sigaction      sa;
    ngx_backtrace_conf_t *bcf;

    for (sig = ngx_backtrace_signals; sig->signo != 0; sig++) {
        if (sig->signo == signo) {
            break;
        }
    }

    bcf = (ngx_backtrace_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx,
                                                ngx_backtrace_module);

    log = bcf->log ? bcf->log : ngx_cycle->log;
    ngx_log_error(NGX_LOG_ERR, log, 0,
                  "nginx coredump by signal %d (%s)", signo, sig->signame);

    ngx_memzero(&sa, sizeof(struct sigaction));
    sa.sa_handler = SIG_DFL;
    sigemptyset(&sa.sa_mask);
    if (sigaction(signo, &sa, NULL) == -1) {
        ngx_log_error(NGX_LOG_ERR, log, ngx_errno,
                      "sigaction(%s) failed", sig->signame);
    }

    if (bcf->max_stack_size == NGX_CONF_UNSET) {
        bcf->max_stack_size = NGX_BACKTRACE_DEFAULT_STACK_MAX_SIZE;
    }

    buffer = ngx_pcalloc(ngx_cycle->pool, sizeof(void *) * bcf->max_stack_size);
    if (buffer == NULL) {
        goto invalid;
    }

    size = backtrace(buffer, bcf->max_stack_size);
    backtrace_symbols_fd(buffer, size, log->file->fd);

invalid:

    kill(ngx_getpid(), signo);
}
コード例 #15
0
int
ngx_shm_dict_handler_incr_int(ngx_shm_zone_t* zone_t, ngx_str_t *key, int count,
		uint32_t exptime,int64_t* res) {

	int 					rc;
	ngx_shm_dict_ctx_t   	*ctx;
	ctx = zone_t->data;

	rc = ngx_shm_dict_inc_int(zone_t, key, count,0, res);
	
	 ngx_log_error(NGX_LOG_DEBUG, ctx->log, 0,
	            "[ah_shm_zone] process=[%d] operator=[%s] zone=[%V] key=[%V] "
	            "count=[%d] exptime=[%d] rc=[%d]\n",ngx_getpid(),"incr",
	            &zone_t->shm.name,key,count,exptime,rc);


	return rc;
}
コード例 #16
0
int
ngx_shm_dict_handler_get(ngx_shm_zone_t *zone_t,ngx_str_t *key,ngx_str_t *value,
		uint32_t *exptime) {

	int 					rc;
	ngx_shm_dict_ctx_t   	*ctx;
	uint8_t 				value_type = SHM_STRING;
	ctx = zone_t->data;

	rc = ngx_shm_dict_get(zone_t, key,value,&value_type,exptime,0);
	
	ngx_log_error(NGX_LOG_DEBUG, ctx->log, 0,
	            "[ah_shm_zone] process=[%d] operator=[%s] zone=[%V] key=[%V] "
	            "value=[%V] exptime=[%d] rc=[%d]\n",ngx_getpid(),"get",
	            &zone_t->shm.name,key,value,*exptime,rc);


	return rc;
}
コード例 #17
0
static ngx_int_t
ngx_rtmp_stat_handler(ngx_http_request_t *r)
{
    ngx_rtmp_stat_loc_conf_t       *slcf;
    ngx_rtmp_core_main_conf_t      *cmcf;
    ngx_rtmp_core_srv_conf_t      **cscf;
    ngx_chain_t                    *cl, *l, **ll, ***lll;
    size_t                          n;
    off_t                           len;
    static u_char                   tbuf[NGX_TIME_T_LEN + 1];
    static u_char                   nbuf[NGX_OFF_T_LEN + 1];

    slcf = ngx_http_get_module_loc_conf(r, ngx_rtmp_stat_module);
    if (slcf->stat == 0) {
        return NGX_DECLINED;
    }

    cmcf = ngx_rtmp_core_main_conf;
    if (cmcf == NULL) {
        goto error;
    }

    cl = NULL;
    ll = &cl;
    lll = &ll;

    NGX_RTMP_STAT_L("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n");
    if (slcf->stylesheet.len) {
        NGX_RTMP_STAT_L("<?xml-stylesheet type=\"text/xsl\" href=\"");
        NGX_RTMP_STAT_ES(&slcf->stylesheet);
        NGX_RTMP_STAT_L("\" ?>\r\n");
    }

    NGX_RTMP_STAT_L("<rtmp>\r\n");

#ifdef NGINX_VERSION
    NGX_RTMP_STAT_L("<version>" NGINX_VERSION "</version>\r\n");
#endif

#ifdef NGX_COMPILER
    NGX_RTMP_STAT_L("<compiler>" NGX_COMPILER "</compiler>\r\n");
#endif
    NGX_RTMP_STAT_L("<built>" __DATE__ " " __TIME__ "</built>\r\n");

    NGX_RTMP_STAT_L("<pid>");
    NGX_RTMP_STAT(nbuf, ngx_snprintf(nbuf, sizeof(nbuf),
                  "%ui", (ngx_uint_t) ngx_getpid()) - nbuf);
    NGX_RTMP_STAT_L("</pid>\r\n");

    NGX_RTMP_STAT_L("<uptime>");
    NGX_RTMP_STAT(tbuf, ngx_snprintf(tbuf, sizeof(tbuf),
                "%T", ngx_cached_time->sec - start_time) - tbuf);
    NGX_RTMP_STAT_L("</uptime>\r\n");

    NGX_RTMP_STAT_L("<naccepted>");
    NGX_RTMP_STAT(nbuf, ngx_snprintf(nbuf, sizeof(nbuf),
                  "%ui", ngx_rtmp_naccepted) - nbuf);
    NGX_RTMP_STAT_L("</naccepted>\r\n");

    ngx_rtmp_stat_bw(r, lll, &ngx_rtmp_bw_in, &ngx_rtmp_bw_out);

    cscf = cmcf->servers.elts;
    for (n = 0; n < cmcf->servers.nelts; ++n, ++cscf) {
        ngx_rtmp_stat_server(r, lll, *cscf);
    }

    NGX_RTMP_STAT_L("</rtmp>\r\n");

    len = 0;
    for (l = cl; l; l = l->next) {
        len += (l->buf->last - l->buf->pos);
    }
    ngx_str_set(&r->headers_out.content_type, "text/xml");
    r->headers_out.content_length_n = len;
    r->headers_out.status = NGX_HTTP_OK;
    ngx_http_send_header(r);
    (*ll)->buf->last_buf = 1;
    return ngx_http_output_filter(r, cl);

error:
    r->headers_out.status = NGX_HTTP_INTERNAL_SERVER_ERROR;
    r->headers_out.content_length_n = 0;
    return ngx_http_send_header(r);
}
コード例 #18
0
ファイル: nginx.c プロジェクト: jaypei/nginx
int ngx_cdecl
main(int argc, char *const *argv)
{
    ngx_int_t         i;
    ngx_log_t        *log;
    ngx_cycle_t      *cycle, init_cycle;
    ngx_core_conf_t  *ccf;

    ngx_debug_init();

    if (ngx_strerror_init() != NGX_OK) {
        return 1;
    }

    if (ngx_get_options(argc, argv) != NGX_OK) {
        return 1;
    }

    if (ngx_show_version) {
        ngx_write_stderr("nginx version: " NGINX_VER NGX_LINEFEED);

        if (ngx_show_help) {
            ngx_write_stderr(
                "Usage: nginx [-?hvVtq] [-s signal] [-c filename] "
                             "[-p prefix] [-g directives]" NGX_LINEFEED
                             NGX_LINEFEED
                "Options:" NGX_LINEFEED
                "  -?,-h         : this help" NGX_LINEFEED
                "  -v            : show version and exit" NGX_LINEFEED
                "  -V            : show version and configure options then exit"
                                   NGX_LINEFEED
                "  -t            : test configuration and exit" NGX_LINEFEED
                "  -q            : suppress non-error messages "
                                   "during configuration testing" NGX_LINEFEED
                "  -s signal     : send signal to a master process: "
                                   "stop, quit, reopen, reload" NGX_LINEFEED
#ifdef NGX_PREFIX
                "  -p prefix     : set prefix path (default: "
                                   NGX_PREFIX ")" NGX_LINEFEED
#else
                "  -p prefix     : set prefix path (default: NONE)" NGX_LINEFEED
#endif
                "  -c filename   : set configuration file (default: "
                                   NGX_CONF_PATH ")" NGX_LINEFEED
                "  -g directives : set global directives out of configuration "
                                   "file" NGX_LINEFEED NGX_LINEFEED
                );
        }

        if (ngx_show_configure) {
            ngx_write_stderr(
#ifdef NGX_COMPILER
                "built by " NGX_COMPILER NGX_LINEFEED
#endif
#if (NGX_SSL)
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
                "TLS SNI support enabled" NGX_LINEFEED
#else
                "TLS SNI support disabled" NGX_LINEFEED
#endif
#endif
                "configure arguments:" NGX_CONFIGURE NGX_LINEFEED);
        }

        if (!ngx_test_config) {
            return 0;
        }
    }

    /* TODO */ ngx_max_sockets = -1;

    ngx_time_init();

#if (NGX_PCRE)
    ngx_regex_init();
#endif

    ngx_pid = ngx_getpid();

    log = ngx_log_init(ngx_prefix);
    if (log == NULL) {
        return 1;
    }

    /* STUB */
#if (NGX_OPENSSL)
    ngx_ssl_init(log);
#endif

    /*
     * init_cycle->log is required for signal handlers and
     * ngx_process_options()
     */

    ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
    init_cycle.log = log;
    ngx_cycle = &init_cycle;

    init_cycle.pool = ngx_create_pool(1024, log);
    if (init_cycle.pool == NULL) {
        return 1;
    }

    if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) {
        return 1;
    }

    if (ngx_process_options(&init_cycle) != NGX_OK) {
        return 1;
    }

    if (ngx_os_init(log) != NGX_OK) {
        return 1;
    }

    /*
     * ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init()
     */

    if (ngx_crc32_table_init() != NGX_OK) {
        return 1;
    }

    if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
        return 1;
    }

    ngx_max_module = 0;
    for (i = 0; ngx_modules[i]; i++) {
        ngx_modules[i]->index = ngx_max_module++;
    }

    cycle = ngx_init_cycle(&init_cycle);
    if (cycle == NULL) {
        if (ngx_test_config) {
            ngx_log_stderr(0, "configuration file %s test failed",
                           init_cycle.conf_file.data);
        }

        return 1;
    }

    if (ngx_test_config) {
        if (!ngx_quiet_mode) {
            ngx_log_stderr(0, "configuration file %s test is successful",
                           cycle->conf_file.data);
        }

        return 0;
    }

    if (ngx_signal) {
        return ngx_signal_process(cycle, ngx_signal);
    }

    ngx_os_status(cycle->log);

    ngx_cycle = cycle;

    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

    if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) {
        ngx_process = NGX_PROCESS_MASTER;
    }

#if !(NGX_WIN32)

    if (ngx_init_signals(cycle->log) != NGX_OK) {
        return 1;
    }

    if (!ngx_inherited && ccf->daemon) {
        if (ngx_daemon(cycle->log) != NGX_OK) {
            return 1;
        }

        ngx_daemonized = 1;
    }

    if (ngx_inherited) {
        ngx_daemonized = 1;
    }

#endif

    if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
        return 1;
    }

    if (cycle->log->file->fd != ngx_stderr) {

        if (ngx_set_stderr(cycle->log->file->fd) == NGX_FILE_ERROR) {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                          ngx_set_stderr_n " failed");
            return 1;
        }
    }

    if (log->file->fd != ngx_stderr) {
        if (ngx_close_file(log->file->fd) == NGX_FILE_ERROR) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          ngx_close_file_n " built-in log failed");
        }
    }

    ngx_use_stderr = 0;

    if (ngx_process == NGX_PROCESS_SINGLE) {
        ngx_single_process_cycle(cycle);

    } else {
        ngx_master_process_cycle(cycle);
    }

    return 0;
}
コード例 #19
0
ファイル: ngx_process.c プロジェクト: 112358wise/ReadNginxSrc
ngx_pid_t
ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data, char *name, ngx_int_t respawn)
{
    u_long     on;
    ngx_pid_t  pid;
    ngx_int_t  s;

    if (respawn >= 0) {//ngx_start_worker_processes-> NGX_PROCESS_RESPAWN ,表示要重新创建进程
        s = respawn;
    } else {//得到当前有多少工作进程创建了ngx_last_process会不断增加的,当然可能有人死了
        for (s = 0; s < ngx_last_process; s++) {
            if (ngx_processes[s].pid == -1) {
                break;
            }
        }
        if (s == NGX_MAX_PROCESSES) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "no more than %d processes can be spawned", NGX_MAX_PROCESSES);
            return NGX_INVALID_PID;
        }
    }

    if (respawn != NGX_PROCESS_DETACHED) {//NGX_PROCESS_DETACHED说明是热代码替换
//不是热代码替换
        /* Solaris 9 still has no AF_LOCAL */
		//创建socketpair,进程之间通信
        if (socketpair(AF_UNIX, SOCK_STREAM, 0, ngx_processes[s].channel) == -1){
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "socketpair() failed while spawning \"%s\"", name);
            return NGX_INVALID_PID;
        }
        ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0, "channel %d:%d", ngx_processes[s].channel[0], ngx_processes[s].channel[1]);
//将socket对设置为非阻塞模式
        if (ngx_nonblocking(ngx_processes[s].channel[0]) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,  ngx_nonblocking_n " failed while spawning \"%s\"",  name);
            ngx_close_channel(ngx_processes[s].channel, cycle->log);
            return NGX_INVALID_PID;
        }
        if (ngx_nonblocking(ngx_processes[s].channel[1]) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, ngx_nonblocking_n " failed while spawning \"%s\"", name);
            ngx_close_channel(ngx_processes[s].channel, cycle->log);
            return NGX_INVALID_PID;
        }

        on = 1;//FIOASYNC 改变O_ASYNC 标志来打开或者关闭套接字的异步 IO 模式。
        if (ioctl(ngx_processes[s].channel[0], FIOASYNC, &on) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "ioctl(FIOASYNC) failed while spawning \"%s\"", name);
            ngx_close_channel(ngx_processes[s].channel, cycle->log);
            return NGX_INVALID_PID;
        }

        if (fcntl(ngx_processes[s].channel[0], F_SETOWN, ngx_pid) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "fcntl(F_SETOWN) failed while spawning \"%s\"", name);
            ngx_close_channel(ngx_processes[s].channel, cycle->log);
            return NGX_INVALID_PID;
        }
//close on exec, not on-fork, 意为如果对描述符设置了FD_CLOEXEC,使用execl执行的程序里,
//此描述符被关闭,不能再使用它,但是在使用fork调用的子进程中,此描述符并不关闭,仍可使用。
        if (fcntl(ngx_processes[s].channel[0], F_SETFD, FD_CLOEXEC) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "fcntl(FD_CLOEXEC) failed while spawning \"%s\"", name);
            ngx_close_channel(ngx_processes[s].channel, cycle->log);
            return NGX_INVALID_PID;
        }
//设置fork对socket对是在子进程依然可用的
        if (fcntl(ngx_processes[s].channel[1], F_SETFD, FD_CLOEXEC) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,  "fcntl(FD_CLOEXEC) failed while spawning \"%s\"", name);
            ngx_close_channel(ngx_processes[s].channel, cycle->log);
            return NGX_INVALID_PID;
        }
        ngx_channel = ngx_processes[s].channel[1];
    } else {//如果是热代码替换,不跟其他进程通信
        ngx_processes[s].channel[0] = -1;
        ngx_processes[s].channel[1] = -1;
    }

    ngx_process_slot = s;//当前在处理这个
    pid = fork();//fork子进程
    switch (pid) {
    case -1:
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "fork() failed while spawning \"%s\"", name);
        ngx_close_channel(ngx_processes[s].channel, cycle->log);
        return NGX_INVALID_PID;
    case 0://子进程调用proc
        ngx_pid = ngx_getpid();//k getpid
        proc(cycle, data);//等于ngx_worker_process_cycle
        //子进程永远也从这回不来了,里面有exit
        break;

    default://父进程默认不干活
        break;
    }

    ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start %s %P", name, pid);
    ngx_processes[s].pid = pid;
    ngx_processes[s].exited = 0;
    if (respawn >= 0) {
        return pid;
    }
//设置ngx_processes数组该项的信息
    ngx_processes[s].proc = proc;//设置工作进程的处理函数ngx_worker_process_cycle,会fork之后调用的
    ngx_processes[s].data = data;
    ngx_processes[s].name = name;//进程名字
    ngx_processes[s].exiting = 0;

    switch (respawn) {
    case NGX_PROCESS_NORESPAWN:
        ngx_processes[s].respawn = 0;
        ngx_processes[s].just_spawn = 0;
        ngx_processes[s].detached = 0;
        break;
    case NGX_PROCESS_JUST_SPAWN:
        ngx_processes[s].respawn = 0;
        ngx_processes[s].just_spawn = 1;
        ngx_processes[s].detached = 0;
        break;

    case NGX_PROCESS_RESPAWN:
        ngx_processes[s].respawn = 1;
        ngx_processes[s].just_spawn = 0;
        ngx_processes[s].detached = 0;
        break;

    case NGX_PROCESS_JUST_RESPAWN:
        ngx_processes[s].respawn = 1;
        ngx_processes[s].just_spawn = 1;
        ngx_processes[s].detached = 0;
        break;

    case NGX_PROCESS_DETACHED:
        ngx_processes[s].respawn = 0;
        ngx_processes[s].just_spawn = 0;
        ngx_processes[s].detached = 1;
        break;
    }
    if (s == ngx_last_process) {
        ngx_last_process++;//递增总进程数
    }
    return pid;
}
コード例 #20
0
ファイル: nginx.c プロジェクト: liuhengloveyou/nginx
int ngx_cdecl main(int argc, char *const *argv)
{
	ngx_int_t         i;
	ngx_log_t        *log;
	ngx_cycle_t      *cycle, init_cycle;
	ngx_core_conf_t  *ccf;

	ngx_debug_init(); // posix 系统上为空

	// 把0到GX_SYS_NERR的strerror信息存到ngx_sys_errlist里
	// 以后错误信息直接从这儿取
	if (ngx_strerror_init() != NGX_OK) {
		return 1;
	}

	// 解析命令行
	if (ngx_get_options(argc, argv) != NGX_OK) {
		return 1;
	}

	// 显示帮助信息
	if (ngx_show_version) {
		ngx_write_stderr("nginx version: " NGINX_VER NGX_LINEFEED);

		if (ngx_show_help) {
			ngx_write_stderr(
				"Usage: nginx [-?hvVtq] [-s signal] [-c filename] "
				"[-p prefix] [-g directives]" NGX_LINEFEED
				NGX_LINEFEED
				"Options:" NGX_LINEFEED
				"  -?,-h         : this help" NGX_LINEFEED
				"  -v            : show version and exit" NGX_LINEFEED
				"  -V            : show version and configure options then exit"
				NGX_LINEFEED
				"  -t            : test configuration and exit" NGX_LINEFEED
				"  -q            : suppress non-error messages "
				"during configuration testing" NGX_LINEFEED
				"  -s signal     : send signal to a master process: "
				"stop, quit, reopen, reload" NGX_LINEFEED
#ifdef NGX_PREFIX
				"  -p prefix     : set prefix path (default: "
				NGX_PREFIX ")" NGX_LINEFEED
#else
				"  -p prefix     : set prefix path (default: NONE)" NGX_LINEFEED
#endif
				"  -c filename   : set configuration file (default: "
				NGX_CONF_PATH ")" NGX_LINEFEED
				"  -g directives : set global directives out of configuration "
				"file" NGX_LINEFEED NGX_LINEFEED
				);
		}

		// 显示编译参数
		if (ngx_show_configure) {
			ngx_write_stderr(
#ifdef NGX_COMPILER
				"built by " NGX_COMPILER NGX_LINEFEED
#endif
#if (NGX_SSL)
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
				"TLS SNI support enabled" NGX_LINEFEED
#else
				"TLS SNI support disabled" NGX_LINEFEED
#endif
#endif
				"configure arguments:" NGX_CONFIGURE NGX_LINEFEED);
		}

		if (!ngx_test_config) {
			return 0;
		}
	}

	/* TODO */ ngx_max_sockets = -1;
	
	ngx_time_init(); // 初始化时钟

#if (NGX_PCRE)
	ngx_regex_init();
#endif

	ngx_pid = ngx_getpid();

	log = ngx_log_init(ngx_prefix); // 初始化错误日志,打开错误日志文件
	if (log == NULL) {
		return 1;
	}

	/* STUB */
#if (NGX_OPENSSL)
	ngx_ssl_init(log);
#endif

	/*
	 * init_cycle->log is required for signal handlers and ngx_process_options()
	 */
	ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
	init_cycle.log = log;
	ngx_cycle = &init_cycle;

	init_cycle.pool = ngx_create_pool(1024, log);
	if (init_cycle.pool == NULL) {
		return 1;
	}

	// 把命令行参数保存在 os/unix/ngx_process.c:30:char           **ngx_argv;
	if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) {
		return 1;
	}

	// 决定NGINX运行的目录
	if (ngx_process_options(&init_cycle) != NGX_OK) {
		return 1;
	}

	if (ngx_os_init(log) != NGX_OK) {
		return 1;
	}

	/*
	 * ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init()
	 */
	if (ngx_crc32_table_init() != NGX_OK) {
		return 1;
	}

	// 通过环境变量NGINX完成socket的继承,继承来的socket将会放到init_cycle的listening数组中。同时可以读取master进程传递的平滑升级信息等等
	if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
		return 1;
	}

	//初始化所有模块的index信息,即对所有模块进行编号
	//ngx_modules数却是在自动编译的时候生成的,位于objs/ngx_modules.c文件中
	ngx_max_module = 0;
	for (i = 0; ngx_modules[i]; i++) {
		ngx_modules[i]->index = ngx_max_module++;
	}

	// 初始化重点都在这儿了
	cycle = ngx_init_cycle(&init_cycle);
	if (cycle == NULL) {
		if (ngx_test_config) {
			ngx_log_stderr(0, "configuration file %s test failed", init_cycle.conf_file.data);
		}

		return 1;
	}

	// nginx -t 测试配置文件
	if (ngx_test_config) {
		if (!ngx_quiet_mode) {
			ngx_log_stderr(0, "configuration file %s test is successful", cycle->conf_file.data);
		}

		return 0;
	}

	// nginx -s
	if (ngx_signal) {
		return ngx_signal_process(cycle, ngx_signal);
	}

	ngx_os_status(cycle->log);

	ngx_cycle = cycle;

	ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

	if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) {
		ngx_process = NGX_PROCESS_MASTER;
	}

#if !(NGX_WIN32)

	if (ngx_init_signals(cycle->log) != NGX_OK) {
		return 1;
	}

	if (!ngx_inherited && ccf->daemon) {
		if (ngx_daemon(cycle->log) != NGX_OK) {
			return 1;
		}

		ngx_daemonized = 1;
	}

	if (ngx_inherited) {
		ngx_daemonized = 1;
	}

#endif

	if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
		return 1;
	}

	if (ngx_log_redirect_stderr(cycle) != NGX_OK) {
		return 1;
	}

	if (log->file->fd != ngx_stderr) {
		if (ngx_close_file(log->file->fd) == NGX_FILE_ERROR) {
			ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, ngx_close_file_n " built-in log failed");
		}
	}

	ngx_use_stderr = 0;

	if (ngx_process == NGX_PROCESS_SINGLE) {
		ngx_single_process_cycle(cycle);
	} else {
		ngx_master_process_cycle(cycle);
	}

	return 0;
}
コード例 #21
0
ファイル: nginx.c プロジェクト: Deelight-fr/Zimbra-1
int ngx_cdecl
main(int argc, char *const *argv)
{
    ngx_int_t         i;
    ngx_log_t        *log;
    ngx_cycle_t      *cycle, init_cycle;
    ngx_core_conf_t  *ccf;
#if !(NGX_WIN32)
    struct rlimit     rlmt;
#endif

    if (ngx_get_options(argc, argv) != NGX_OK) {
        return 1;
    }

    if (ngx_show_version) {
        ngx_log_stderr(0, "nginx version: " NGINX_VER);

        if (ngx_show_help) {
            ngx_log_stderr(0,
                "Usage: nginx [-?hvVt] [-s signal] [-c filename] "
                             "[-p prefix] [-g directives]" CRLF CRLF
                "Options:" CRLF
                "  -?,-h         : this help" CRLF
                "  -v            : show version and exit" CRLF
                "  -V            : show version and configure options then exit"
                                   CRLF
                "  -t            : test configuration and exit" CRLF
                "  -s signal     : send signal to a master process: "
                                   "stop, quit, reopen, reload" CRLF
#ifdef NGX_PREFIX
                "  -p prefix     : set prefix path (default: "
                                   NGX_PREFIX ")" CRLF
#else
                "  -p prefix     : set prefix path (default: NONE)" CRLF
#endif
                "  -c filename   : set configuration file (default: "
                                   NGX_CONF_PATH ")" CRLF
                "  -g directives : set global directives out of configuration "
                                   "file" CRLF
                );
        }

        if (ngx_show_configure) {
#ifdef NGX_COMPILER
            ngx_log_stderr(0, "built by " NGX_COMPILER);
#endif
#if (NGX_SSL)
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
            ngx_log_stderr(0, "TLS SNI support enabled");
#else
            ngx_log_stderr(0, "TLS SNI support disabled");
#endif
#endif
            ngx_log_stderr(0, "configure arguments:" NGX_CONFIGURE);
        }

        if (!ngx_test_config) {
            return 0;
        }
    }

#if (NGX_FREEBSD)
    ngx_debug_init();
#endif

    /* TODO */ ngx_max_sockets = -1;

    ngx_time_init();

#if (NGX_PCRE)
    ngx_regex_init();
#endif

    ngx_pid = ngx_getpid();

    log = ngx_log_init(ngx_prefix);
    if (log == NULL) {
        return 1;
    }

    /* STUB */
#if (NGX_OPENSSL)
    ngx_ssl_init(log);
#endif

    /*
     * init_cycle->log is required for signal handlers and
     * ngx_process_options()
     */

    ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
    init_cycle.log = log;
    ngx_cycle = &init_cycle;

    init_cycle.pool = ngx_create_pool(1024, log);
    if (init_cycle.pool == NULL) {
        return 1;
    }

    if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) {
        return 1;
    }

    if (ngx_process_options(&init_cycle) != NGX_OK) {
        return 1;
    }

    if (ngx_os_init(log) != NGX_OK) {
        return 1;
    }

    /*
     * ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init()
     */

    if (ngx_crc32_table_init() != NGX_OK) {
        return 1;
    }

    if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
        return 1;
    }

    ngx_max_module = 0;
    for (i = 0; ngx_modules[i]; i++) {
        ngx_modules[i]->index = ngx_max_module++;
    }

    cycle = ngx_init_cycle(&init_cycle);
    if (cycle == NULL) {
        if (ngx_test_config) {
            ngx_log_stderr(0, "configuration file %s test failed",
                           init_cycle.conf_file.data);
        }

        return 1;
    }

    if (ngx_test_config) {
        ngx_log_stderr(0, "configuration file %s test is successful",
                       cycle->conf_file.data);
        return 0;
    }

    if (ngx_signal) {
        return ngx_signal_process(cycle, ngx_signal);
    }

    ngx_os_status(cycle->log);

    ngx_cycle = cycle;

    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

    if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) {
        ngx_process = NGX_PROCESS_MASTER;
    }

#if !(NGX_WIN32)

    if (geteuid() == 0) {
        if (ccf->rlimit_nofile != NGX_CONF_UNSET) {
            rlmt.rlim_cur = (rlim_t) ccf->rlimit_nofile;
            rlmt.rlim_max = (rlim_t) ccf->rlimit_nofile;

            if (setrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
                ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                    "setrlimit(RLIMIT_NOFILE, %i) failed", ccf->rlimit_nofile);
            }
        }

        if (ccf->rlimit_core != NGX_CONF_UNSET_SIZE) {
            rlmt.rlim_cur = (rlim_t) ccf->rlimit_core;
            rlmt.rlim_max = (rlim_t) ccf->rlimit_core;

            if (setrlimit(RLIMIT_CORE, &rlmt) == -1) {
                ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                    "setrlimit(RLIMIT_CORE, %i) failed", ccf->rlimit_core);
            }
        }

#ifdef RLIMIT_SIGPENDING
        if (ccf->rlimit_sigpending != NGX_CONF_UNSET) {
            rlmt.rlim_cur = (rlim_t) ccf->rlimit_sigpending;
            rlmt.rlim_max = (rlim_t) ccf->rlimit_sigpending;

            if (setrlimit(RLIMIT_SIGPENDING, &rlmt) == -1) {
                ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                    "setrlimit(RLIMIT_SIGPENDING, %i) failed", ccf->rlimit_sigpending);
            }
        }
#endif

        if (setgid(ccf->group) == -1) {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                "setgid(%d) failed", ccf->group);
            /* fatal */
            exit(2);
        }

        if (initgroups(ccf->username, ccf->group) == -1) {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                "initgroups(%s, %d) failed", ccf->username, ccf->group);
        }

        if (setuid(ccf->user) == -1) {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                "setuid(%d) failed", ccf->user);
            /* fatal */
            exit(2);
        }
    }

    if (ngx_init_signals(cycle->log) != NGX_OK) {
        return 1;
    }

    if (!ngx_inherited && ccf->daemon) {
        if (ngx_daemon(cycle->log) != NGX_OK) {
            return 1;
        }

        ngx_daemonized = 1;
    }

#endif

    if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
        return 1;
    }

    if (cycle->log->file->fd != ngx_stderr) {

        if (ngx_set_stderr(cycle->log->file->fd) == NGX_FILE_ERROR) {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                          ngx_set_stderr_n " failed");
            return 1;
        }
    }

    if (log->file->fd != ngx_stderr) {
        if (ngx_close_file(log->file->fd) == NGX_FILE_ERROR) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          ngx_close_file_n " built-in log failed");
        }
    }

    ngx_use_stderr = 0;

    if (ngx_process == NGX_PROCESS_SINGLE) {
        ngx_single_process_cycle(cycle);

    } else {
        ngx_master_process_cycle(cycle);
    }

    return 0;
}
コード例 #22
0
int ngx_cdecl
main(int argc, char *const *argv)
{



    ngx_int_t         i;
    ngx_log_t        *log;
    ngx_cycle_t      *cycle, init_cycle;
    ngx_core_conf_t  *ccf;

    ngx_debug_init();

    if (ngx_strerror_init() != NGX_OK) {
        return 1;
    }

    if (ngx_get_options(argc, argv) != NGX_OK) {
        return 1;
    }


    /* TODO */ ngx_max_sockets = -1;

    ngx_time_init();


    ngx_pid = ngx_getpid();

    log = ngx_log_init(ngx_prefix);
    if (log == NULL) {
        return 1;
    }

    /* STUB */


    /*
     * init_cycle->log is required for signal handlers and
     * ngx_process_options()
     */

    ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
    init_cycle.log = log;
    ngx_cycle = &init_cycle;

    init_cycle.pool = ngx_create_pool(1024, log);
    if (init_cycle.pool == NULL) {
        return 1;
    }

    if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) {
        return 1;
    }

    if (ngx_process_options(&init_cycle) != NGX_OK) {
        return 1;
    }

    if (ngx_os_init(log) != NGX_OK) {
        return 1;
    }

    /*
     * ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init()
     */

    if (ngx_crc32_table_init() != NGX_OK) {
        return 1;
    }

    if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
        return 1;
    }

    ngx_max_module = 0;
    for (i = 0; ngx_modules[i]; i++) {
        ngx_modules[i]->index = ngx_max_module++;
    }

    cycle = ngx_init_cycle(&init_cycle);
    if (cycle == NULL) {
        if (ngx_test_config) {
            ngx_log_stderr(0, "configuration file %s test failed",
                           init_cycle.conf_file.data);
        }

        return 1;
    }

    if (ngx_test_config) {
        if (!ngx_quiet_mode) {
            ngx_log_stderr(0, "configuration file %s test is successful",
                           cycle->conf_file.data);
        }

        return 0;
    }

    if (ngx_signal) {
        return ngx_signal_process(cycle, ngx_signal);
    }

    ngx_os_status(cycle->log);

    ngx_cycle = cycle;

    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

    if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) {
        ngx_process = NGX_PROCESS_MASTER;
    }



//    if (ngx_init_signals(cycle->log) != NGX_OK) {
//        return 1;
//    }
//
//    if (!ngx_inherited && ccf->daemon) {
//        if (ngx_daemon(cycle->log) != NGX_OK) {
//            return 1;
//        }
//
//        ngx_daemonized = 1;
//    }
//
//    if (ngx_inherited) {
//        ngx_daemonized = 1;
//    }



    if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
        return 1;
    }

    if (ngx_log_redirect_stderr(cycle) != NGX_OK) {
        return 1;
    }

    if (log->file->fd != ngx_stderr) {
        if (ngx_close_file(log->file->fd) == NGX_FILE_ERROR) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          ngx_close_file_n " built-in log failed");
        }
    }

  ngx_use_stderr = 0;
//    if (ngx_process == NGX_PROCESS_SINGLE) {
        ngx_single_process_cycle(cycle);

//    } else {
//        ngx_master_process_cycle(cycle);
//    }

    return 0;
}
コード例 #23
0
ファイル: nginx.c プロジェクト: ryanliao360/nginx
int ngx_cdecl
main(int argc, char *const *argv)
{
    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_strerror_init() != NGX_OK) {
        return 1;
    }

    if (ngx_get_options(argc, argv) != NGX_OK) {
        return 1;
    }

    if (ngx_show_version) {
        ngx_show_version_info();

        if (!ngx_test_config) {
            return 0;
        }
    }

    /* TODO */ ngx_max_sockets = -1;

    ngx_time_init();

#if (NGX_PCRE)
    ngx_regex_init();
#endif

    ngx_pid = ngx_getpid();

    log = ngx_log_init(ngx_prefix);
    if (log == NULL) {
        return 1;
    }

    /* STUB */
#if (NGX_OPENSSL)
    ngx_ssl_init(log);
#endif

    /*
     * init_cycle->log is required for signal handlers and
     * ngx_process_options()
     */

    ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
    init_cycle.log = log;
    ngx_cycle = &init_cycle;

    init_cycle.pool = ngx_create_pool(1024, log);
    if (init_cycle.pool == NULL) {
        return 1;
    }

    if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) {
        return 1;
    }

    if (ngx_process_options(&init_cycle) != NGX_OK) {
        return 1;
    }

    if (ngx_os_init(log) != NGX_OK) {
        return 1;
    }

    /*
     * ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init()
     */

    if (ngx_crc32_table_init() != NGX_OK) {
        return 1;
    }

    if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
        return 1;
    }

    ngx_max_module = 0;
    for (i = 0; ngx_modules[i]; i++) {
        ngx_modules[i]->index = ngx_max_module++;
    }

    cycle = ngx_init_cycle(&init_cycle);
    if (cycle == NULL) {
        if (ngx_test_config) {
            ngx_log_stderr(0, "configuration file %s test failed",
                           init_cycle.conf_file.data);
        }

        return 1;
    }

    if (ngx_test_config) {
        if (!ngx_quiet_mode) {
            ngx_log_stderr(0, "configuration file %s test is successful",
                           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;
    }

    if (ngx_signal) {
        return ngx_signal_process(cycle, ngx_signal);
    }

    ngx_os_status(cycle->log);

    ngx_cycle = cycle;

    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

    if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) {
        ngx_process = NGX_PROCESS_MASTER;
    }

#if !(NGX_WIN32)

    if (ngx_init_signals(cycle->log) != NGX_OK) {
        return 1;
    }

    if (!ngx_inherited && ccf->daemon) {
        if (ngx_daemon(cycle->log) != NGX_OK) {
            return 1;
        }

        ngx_daemonized = 1;
    }

    if (ngx_inherited) {
        ngx_daemonized = 1;
    }

#endif

    if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
        return 1;
    }

    if (ngx_log_redirect_stderr(cycle) != NGX_OK) {
        return 1;
    }

    if (log->file->fd != ngx_stderr) {
        if (ngx_close_file(log->file->fd) == NGX_FILE_ERROR) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          ngx_close_file_n " built-in log failed");
        }
    }

    ngx_use_stderr = 0;

    if (ngx_process == NGX_PROCESS_SINGLE) {
        ngx_single_process_cycle(cycle);

    } else {
        ngx_master_process_cycle(cycle);
    }

    return 0;
}
コード例 #24
0
ファイル: ngx_process.c プロジェクト: AloneRoad/MTS
ngx_pid_t
ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data,
    char *name, ngx_int_t respawn)
{
    u_long     on;
    ngx_pid_t  pid;
    ngx_int_t  s;

    if (respawn >= 0) {
        s = respawn;

    } else {
        for (s = 0; s < ngx_last_process; s++) {
            if (ngx_processes[s].pid == -1) {
                break;
            }
        }

        if (s == NGX_MAX_PROCESSES) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
                          "no more than %d processes can be spawned",
                          NGX_MAX_PROCESSES);
            return NGX_INVALID_PID;
        }
    }


    if (respawn != NGX_PROCESS_DETACHED) {

        /* Solaris 9 still has no AF_LOCAL */

        if (socketpair(AF_UNIX, SOCK_STREAM, 0, ngx_processes[s].channel) == -1)
        {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "socketpair() failed while spawning \"%s\"", name);
            return NGX_INVALID_PID;
        }

        ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
                       "channel %d:%d",
                       ngx_processes[s].channel[0],
                       ngx_processes[s].channel[1]);

        if (ngx_nonblocking(ngx_processes[s].channel[0]) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          ngx_nonblocking_n " failed while spawning \"%s\"",
                          name);
            ngx_close_channel(ngx_processes[s].channel, cycle->log);
            return NGX_INVALID_PID;
        }

        if (ngx_nonblocking(ngx_processes[s].channel[1]) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          ngx_nonblocking_n " failed while spawning \"%s\"",
                          name);
            ngx_close_channel(ngx_processes[s].channel, cycle->log);
            return NGX_INVALID_PID;
        }

        on = 1;
        if (ioctl(ngx_processes[s].channel[0], FIOASYNC, &on) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "ioctl(FIOASYNC) failed while spawning \"%s\"", name);
            ngx_close_channel(ngx_processes[s].channel, cycle->log);
            return NGX_INVALID_PID;
        }

        if (fcntl(ngx_processes[s].channel[0], F_SETOWN, ngx_pid) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "fcntl(F_SETOWN) failed while spawning \"%s\"", name);
            ngx_close_channel(ngx_processes[s].channel, cycle->log);
            return NGX_INVALID_PID;
        }

        if (fcntl(ngx_processes[s].channel[0], F_SETFD, FD_CLOEXEC) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "fcntl(FD_CLOEXEC) failed while spawning \"%s\"",
                           name);
            ngx_close_channel(ngx_processes[s].channel, cycle->log);
            return NGX_INVALID_PID;
        }

        if (fcntl(ngx_processes[s].channel[1], F_SETFD, FD_CLOEXEC) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "fcntl(FD_CLOEXEC) failed while spawning \"%s\"",
                           name);
            ngx_close_channel(ngx_processes[s].channel, cycle->log);
            return NGX_INVALID_PID;
        }

        ngx_channel = ngx_processes[s].channel[1];

    } else {
        ngx_processes[s].channel[0] = -1;
        ngx_processes[s].channel[1] = -1;
    }

    ngx_process_slot = s;


    pid = fork();

    switch (pid) {

    case -1:
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      "fork() failed while spawning \"%s\"", name);
        ngx_close_channel(ngx_processes[s].channel, cycle->log);
        return NGX_INVALID_PID;

    case 0:
        ngx_pid = ngx_getpid();
        proc(cycle, data);
        break;

    default:
        break;
    }

    ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start %s %P", name, pid);

    ngx_processes[s].pid = pid;
    ngx_processes[s].exited = 0;

    if (respawn >= 0) {
        return pid;
    }

    ngx_processes[s].proc = proc;
    ngx_processes[s].data = data;
    ngx_processes[s].name = name;
    ngx_processes[s].exiting = 0;

    switch (respawn) {

    case NGX_PROCESS_NORESPAWN:
        ngx_processes[s].respawn = 0;
        ngx_processes[s].just_spawn = 0;
        ngx_processes[s].detached = 0;
        break;

    case NGX_PROCESS_JUST_SPAWN:
        ngx_processes[s].respawn = 0;
        ngx_processes[s].just_spawn = 1;
        ngx_processes[s].detached = 0;
        break;

    case NGX_PROCESS_RESPAWN:
        ngx_processes[s].respawn = 1;
        ngx_processes[s].just_spawn = 0;
        ngx_processes[s].detached = 0;
        break;

    case NGX_PROCESS_JUST_RESPAWN:
        ngx_processes[s].respawn = 1;
        ngx_processes[s].just_spawn = 1;
        ngx_processes[s].detached = 0;
        break;

    case NGX_PROCESS_DETACHED:
        ngx_processes[s].respawn = 0;
        ngx_processes[s].just_spawn = 0;
        ngx_processes[s].detached = 1;
        break;
    }

    if (s == ngx_last_process) {
        ngx_last_process++;
    }

    return pid;
}
コード例 #25
0
int query_result_to_cstring(const char* path, char res_string[], size_t size, ngx_http_request_t *r)
{
    int ret = 0;
    res_string[0] = '\0';

    static MYSQL *kconn = NULL;
    static int kconnected = 0;
    static int kconnect_times = 0;
    static int kquery_times = 0;

    if(!kconnected) {
        kconnect_times ++;

        char server[] = "localhost";
        char user[] = "root";
        char password[] = "[email protected]";
        char database[] = "notetask";
    
        kconn = mysql_init(NULL);
    
        if (!mysql_real_connect(kconn, server,user, password, database, 0, NULL, 0)) {
            PRINTF_ERROR("mysql connect error : %s\n", mysql_error(kconn));
            mysql_close(kconn);
            mysql_library_end();
            kconn = NULL;
            kconnected = 0;
            ret = -1;
            goto finish;
        }
            else {
            PRINTF_DEBUG("mysql connect OK [%d].\n", getpid());
            kconnected = 1;
            }
    }

    //根据请求的path, 组合查询语句.
    #define LEN_QUERY_STRING (1024)
    char query_string[LEN_QUERY_STRING];
    snprintf(query_string, LEN_QUERY_STRING, "%s", "select * from notetask"); 

    int ret_query = mysql_query(kconn, query_string);
    kquery_times ++;
    if(ret_query) {
        PRINTF_ERROR("mysql query error : %s\n", mysql_error(kconn));
        mysql_close(kconn);
        mysql_library_end();
        kconn = NULL;
        kconnected = 0;
        ret = -1;
        goto finish;
    }

    MYSQL_ROW sqlrow;
    MYSQL_RES *res_ptr;

    size_t len = 0;

    res_ptr = mysql_store_result(kconn);

    int64_t uid = 100;
    int type = 1;
    int count = 18;
    int version = 667;
    int status = 0;

    const char* title = "当前任务";
    int page = 1;
    int code = 200;
    int success = 1;
    const char* message = "";
    len += snprintf(res_string, size-len, 
            "{"
                "\"notetasks\":{"
                    "\"uid\":%"PRIu64","
                    "\"type\":%d,"
                    "\"count\":%d,"
                    "\"version\":%d,"
                    "\"server\":\"%d.%d.%d.%d\","
                    "\"status\":%d"
                "},"
                "\"page\":{"
                    "\"title\":\"%s\","
                    "\"page\":%d"
                "},"
                "\"code\":%d,"
                "\"success\":%s,"
                "\"message\":\"%s\","
                "\"notes\":[", 
                    uid,
                    type,
                    count,
                    version,
                    ngx_getpid(), ngx_log_tid, kconnect_times, kquery_times,
                    status,
                    title, 
                    page,
                    code,
                    success?"true":"false",
                    message);

    int row_number = 0;

    if(res_ptr) {
        while((sqlrow = mysql_fetch_row(res_ptr)) && len + 1 < size) {

            row_number ++;

            len += snprintf(res_string + len, size - len, 
                    "%s{"
                        "\"uid\":%s," 
                        "\"status\":%s," 
                        "\"startDateTime\":\"%s\"," 
                        "\"finishDateTime\":\"%s\"," 
                        "\"commitDateTime\":\"%s\"," 
                        "\"updateDateTime\":\"%s\"," 
                        "\"content\":\"%s\","
                        "\"isShared\":%s,"
                        "\"isOnlyLocal\":%s,"
                        "\"isOnlyWorkday\":%s,"
                        "\"isDailyRepeat\":%s,"
                        "\"isWeeklyRepeat\":%s,"
                        "\"isYearlyRepeat\":%s,"
                        "\"commentNumber\":%ld,"
                        "\"likeNumber\":%ld"
                    "}", 
                    row_number > 1 ? "," : "", 
                    sqlrow[1],
                    sqlrow[2],
                    sqlrow[3],
                    sqlrow[4],
                    sqlrow[5],
                    sqlrow[6],
                    sqlrow[7],
                    sqlrow[8],
                    sqlrow[9],
                    sqlrow[10],
                    sqlrow[11],
                    sqlrow[12],
                    sqlrow[13],
                    atol(sqlrow[14]),
                    atol(sqlrow[15])
                        );
        }

        if(len+1 < size) {
            len += snprintf(res_string + len, size - len, 
                "]"
                "}");
        }

        mysql_free_result(res_ptr);
        res_ptr = NULL;
    }
    else {
        PRINTF_ERROR("mysql_use_result error : %s.\n", mysql_error(kconn));
        mysql_close(kconn);
        mysql_library_end();
        kconn = NULL;
        kconnected = 0;
        ret = -1;
        goto finish;
    }

finish:
    return ret;
}
コード例 #26
0
static char * xml_log_merge_conf(ngx_conf_t *cf, void *parent, void *child) {
    xml_log_conf_t *prev = parent;
    xml_log_conf_t *conf = child;
    ngx_open_file_t *file;
    ngx_str_t *str;

    ngx_conf_merge_path_value(conf->path, prev->path, "/",1,2,0,ngx_garbage_collector_temp_handler,cf);

    if((&conf->path->name)->len > 1)  {
	conf->enable=1;
	str=ngx_pcalloc(cf->pool,sizeof(ngx_str_t));
	str->data=ngx_pcalloc(cf->pool,(&conf->path->name)->len+15);
	(&conf->path->name)->data[(&conf->path->name)->len]=0;
	ngx_snprintf(str->data,(&conf->path->name)->len+15,"%s/%d.xml.tmp",(&conf->path->name)->data,ngx_getpid());
	if((conf->file=ngx_conf_open_file(cf->cycle,str)) == NULL) return NGX_CONF_ERROR;
    }
    return NGX_CONF_OK;
}
コード例 #27
0
ファイル: ngx_process.c プロジェクト: XiaoxiaoxiaoCoder/Nginx
/*
 * 创建进程
 */
ngx_pid_t
ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data,
    char *name, ngx_int_t respawn)
{
    u_long     on;
    ngx_pid_t  pid;
    ngx_int_t  s;

    if (respawn >= 0) {
        s = respawn;

    } else {
        /*在全局进程表 ngx_processes 中查找第一个空的结构,用来存放新创建的进程的信息*/
        for (s = 0; s < ngx_last_process; s++) {
            if (ngx_processes[s].pid == -1) {
                break;
            }
        }

        if (s == NGX_MAX_PROCESSES) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
                          "no more than %d processes can be spawned",
                          NGX_MAX_PROCESSES);
            return NGX_INVALID_PID;
        }
    }


    if (respawn != NGX_PROCESS_DETACHED) {

        /* Solaris 9 still has no AF_LOCAL */

        /*调用 socketpair 创建一对互相连接的 unix域socket,用于进程间的全双工通信*/
        if (socketpair(AF_UNIX, SOCK_STREAM, 0, ngx_processes[s].channel) == -1)
        {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "socketpair() failed while spawning \"%s\"", name);
            return NGX_INVALID_PID;
        }

        ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
                       "channel %d:%d",
                       ngx_processes[s].channel[0],
                       ngx_processes[s].channel[1]);

        /*将用于进程通信的 socket 设置成非阻塞的*/
        if (ngx_nonblocking(ngx_processes[s].channel[0]) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          ngx_nonblocking_n " failed while spawning \"%s\"",
                          name);
            ngx_close_channel(ngx_processes[s].channel, cycle->log);
            return NGX_INVALID_PID;
        }

        if (ngx_nonblocking(ngx_processes[s].channel[1]) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          ngx_nonblocking_n " failed while spawning \"%s\"",
                          name);
            ngx_close_channel(ngx_processes[s].channel, cycle->log);
            return NGX_INVALID_PID;
        }

        on = 1;
        /*设置成信号驱动异步IO,有IO时内核发送SIGIO信号*/
        if (ioctl(ngx_processes[s].channel[0], FIOASYNC, &on) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "ioctl(FIOASYNC) failed while spawning \"%s\"", name);
            ngx_close_channel(ngx_processes[s].channel, cycle->log);
            return NGX_INVALID_PID;
        }

        /*设置将接受 SIGIO 和 SIGURG 信号的进程id*/
        if (fcntl(ngx_processes[s].channel[0], F_SETOWN, ngx_pid) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "fcntl(F_SETOWN) failed while spawning \"%s\"", name);
            ngx_close_channel(ngx_processes[s].channel, cycle->log);
            return NGX_INVALID_PID;
        }

        /*当执行 exec 时关闭描述符*/
        if (fcntl(ngx_processes[s].channel[0], F_SETFD, FD_CLOEXEC) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "fcntl(FD_CLOEXEC) failed while spawning \"%s\"",
                           name);
            ngx_close_channel(ngx_processes[s].channel, cycle->log);
            return NGX_INVALID_PID;
        }

        if (fcntl(ngx_processes[s].channel[1], F_SETFD, FD_CLOEXEC) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "fcntl(FD_CLOEXEC) failed while spawning \"%s\"",
                           name);
            ngx_close_channel(ngx_processes[s].channel, cycle->log);
            return NGX_INVALID_PID;
        }
        /*当前子进程的描述符*/
        ngx_channel = ngx_processes[s].channel[1];

    } else {
        ngx_processes[s].channel[0] = -1;
        ngx_processes[s].channel[1] = -1;
    }

    /*新创建进的进程在 ngx_processes 数组中的下标*/
    ngx_process_slot = s;


    pid = fork();

    switch (pid) {

    case -1:
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      "fork() failed while spawning \"%s\"", name);
        ngx_close_channel(ngx_processes[s].channel, cycle->log);
        return NGX_INVALID_PID;

    case 0:                         //子进程
        ngx_pid = ngx_getpid();
        proc(cycle, data);
        break;

    default:
        break;
    }

    ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start %s %P", name, pid);

    /*新创建的进程放入 master 主进程的 ngx_processes 数组中*/
    ngx_processes[s].pid = pid;
    ngx_processes[s].exited = 0;

    if (respawn >= 0) {
        return pid;
    }

    ngx_processes[s].proc = proc;
    ngx_processes[s].data = data;
    ngx_processes[s].name = name;
    ngx_processes[s].exiting = 0;

    switch (respawn) {

    case NGX_PROCESS_NORESPAWN:
        ngx_processes[s].respawn = 0;
        ngx_processes[s].just_spawn = 0;
        ngx_processes[s].detached = 0;
        break;

    case NGX_PROCESS_JUST_SPAWN:
        ngx_processes[s].respawn = 0;
        ngx_processes[s].just_spawn = 1;
        ngx_processes[s].detached = 0;
        break;

    case NGX_PROCESS_RESPAWN:
        ngx_processes[s].respawn = 1;
        ngx_processes[s].just_spawn = 0;
        ngx_processes[s].detached = 0;
        break;

    case NGX_PROCESS_JUST_RESPAWN:
        ngx_processes[s].respawn = 1;
        ngx_processes[s].just_spawn = 1;
        ngx_processes[s].detached = 0;
        break;

    case NGX_PROCESS_DETACHED:
        ngx_processes[s].respawn = 0;
        ngx_processes[s].just_spawn = 0;
        ngx_processes[s].detached = 1;
        break;
    }

    if (s == ngx_last_process) {
        ngx_last_process++;
    }

    return pid;
}
コード例 #28
0
ファイル: nginx.c プロジェクト: sykpour/nginx1.8.0
int ngx_cdecl
main(int argc, char *const *argv)
{
    ngx_int_t         i;
    ngx_log_t        *log;
    ngx_cycle_t      *cycle, init_cycle;
    ngx_core_conf_t  *ccf;

    ngx_debug_init();

    if (ngx_strerror_init() != NGX_OK) {		//初始化错误编号的错误字符串数组
        return 1;
    }

    if (ngx_get_options(argc, argv) != NGX_OK) {	//命令行处理
        return 1;
    }

	//如果ngx_show_version由上面的ngx_get_options置为1
    if (ngx_show_version) {
        ngx_write_stderr("nginx version: " NGINX_VER_BUILD NGX_LINEFEED);	//显示宏定义

        if (ngx_show_help) {
            ngx_write_stderr(
                "Usage: nginx [-?hvVtq] [-s signal] [-c filename] "
                             "[-p prefix] [-g directives]" NGX_LINEFEED
                             NGX_LINEFEED
                "Options:" NGX_LINEFEED
                "  -?,-h         : this help" NGX_LINEFEED
                "  -v            : show version and exit" NGX_LINEFEED
                "  -V            : show version and configure options then exit"
                                   NGX_LINEFEED
                "  -t            : test configuration and exit" NGX_LINEFEED
                "  -q            : suppress non-error messages "
                                   "during configuration testing" NGX_LINEFEED
                "  -s signal     : send signal to a master process: "
                                   "stop, quit, reopen, reload" NGX_LINEFEED
#ifdef NGX_PREFIX
                "  -p prefix     : set prefix path (default: "
                                   NGX_PREFIX ")" NGX_LINEFEED
#else
                "  -p prefix     : set prefix path (default: NONE)" NGX_LINEFEED
#endif
                "  -c filename   : set configuration file (default: "
                                   NGX_CONF_PATH ")" NGX_LINEFEED
                "  -g directives : set global directives out of configuration "
                                   "file" NGX_LINEFEED NGX_LINEFEED
                );
        }

        if (ngx_show_configure) {

#ifdef NGX_COMPILER
            ngx_write_stderr("built by " NGX_COMPILER NGX_LINEFEED);
#endif

#if (NGX_SSL)
            if (SSLeay() == SSLEAY_VERSION_NUMBER) {
                ngx_write_stderr("built with " OPENSSL_VERSION_TEXT
                                 NGX_LINEFEED);
            } else {
                ngx_write_stderr("built with " OPENSSL_VERSION_TEXT
                                 " (running with ");
                ngx_write_stderr((char *) (uintptr_t)
                                 SSLeay_version(SSLEAY_VERSION));
                ngx_write_stderr(")" NGX_LINEFEED);
            }
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
            ngx_write_stderr("TLS SNI support enabled" NGX_LINEFEED);
#else
            ngx_write_stderr("TLS SNI support disabled" NGX_LINEFEED);
#endif
#endif

            ngx_write_stderr("configure arguments:" NGX_CONFIGURE NGX_LINEFEED);
        }

        if (!ngx_test_config) {
            return 0;
        }
    }

    /* TODO */ ngx_max_sockets = -1;

    ngx_time_init();			//时间初始化

#if (NGX_PCRE)
    ngx_regex_init();
#endif

    ngx_pid = ngx_getpid();		//获得主进程pid

    log = ngx_log_init(ngx_prefix);		//初始化log	
    if (log == NULL) {
        return 1;
    }

    /* STUB */
#if (NGX_OPENSSL)
    ngx_ssl_init(log);
#endif

    /*
     * init_cycle->log is required for signal handlers and
     * ngx_process_options()
     */

	//构造一个init_cycle,旧的预处理
    ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
    init_cycle.log = log;
    ngx_cycle = &init_cycle;		//init_cycle是在栈中的

    init_cycle.pool = ngx_create_pool(1024, log);		//1K大小内存
    if (init_cycle.pool == NULL) {
        return 1;
    }

	//拷贝一份argv
    if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) {
        return 1;
    }

	//处理命令行选项
    if (ngx_process_options(&init_cycle) != NGX_OK) {	
        return 1;
    }

    if (ngx_os_init(log) != NGX_OK) {
        return 1;
    }

    /*
     * ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init()
     */

    if (ngx_crc32_table_init() != NGX_OK) {
        return 1;
    }

	//从环境变量中继承一些监听描述符,用于平滑升级
    if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
        return 1;
    }

	//设置模块的编号,从0开始计数
    ngx_max_module = 0;
    for (i = 0; ngx_modules[i]; i++) {
        ngx_modules[i]->index = ngx_max_module++;
    }

    cycle = ngx_init_cycle(&init_cycle);	//创建新的cycle
    if (cycle == NULL) {
        if (ngx_test_config) {
            ngx_log_stderr(0, "configuration file %s test failed",
                           init_cycle.conf_file.data);
        }

        return 1;
    }

    if (ngx_test_config) {
        if (!ngx_quiet_mode) {
            ngx_log_stderr(0, "configuration file %s test is successful",
                           cycle->conf_file.data);
        }

        return 0;
    }

    if (ngx_signal) {		//如果要向指定的进程发送信号
        return ngx_signal_process(cycle, ngx_signal);
    }

    ngx_os_status(cycle->log);

    ngx_cycle = cycle;

    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

    if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) {
        ngx_process = NGX_PROCESS_MASTER;		//以多进程方式工作
    }

#if !(NGX_WIN32)

    if (ngx_init_signals(cycle->log) != NGX_OK) {		//初始化信号相关操作
        return 1;
    }

    if (!ngx_inherited && ccf->daemon) {
        if (ngx_daemon(cycle->log) != NGX_OK) {		//以守护进程来运行
            return 1;
        }

        ngx_daemonized = 1;
    }

    if (ngx_inherited) {
        ngx_daemonized = 1;
    }

#endif

	//创建进程的pid的文件
    if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
        return 1;
    }

    if (ngx_log_redirect_stderr(cycle) != NGX_OK) {
        return 1;
    }

    if (log->file->fd != ngx_stderr) {
        if (ngx_close_file(log->file->fd) == NGX_FILE_ERROR) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          ngx_close_file_n " built-in log failed");
        }
    }

    ngx_use_stderr = 0;

    if (ngx_process == NGX_PROCESS_SINGLE) {
        ngx_single_process_cycle(cycle);

    } else {
        ngx_master_process_cycle(cycle);		//以多进程方式运行
    }

    return 0;
}
コード例 #29
0
//1.时间、正则、错误日志、ssl等初始化
//2.读入命令行参数
//3.OS相关初始化
//4.读入并解析配置
//5.核心模块初始化
//6.创建各种临时文件和目录
//7.创建共享内存
//8.打开listen的端口
//9.所有模块初始化
//10.启动worker进程
int ngx_cdecl
main(int argc, char *const *argv)
{
    ngx_int_t         i;
    ngx_log_t        *log;
    ngx_cycle_t      *cycle, init_cycle;
    ngx_core_conf_t  *ccf;

#if (NGX_FREEBSD)
    ngx_debug_init();
#endif

    if (ngx_strerror_init() != NGX_OK) {
        return 1;
    }

    //获取参数和配置参数,比如命令是nginx -v 那么ngx_show_version就设置为1
    if (ngx_get_options(argc, argv) != NGX_OK) {
        return 1;
    }

    if (ngx_show_version) {
        ngx_write_stderr("nginx version: " NGINX_VER NGX_LINEFEED);

        if (ngx_show_help) {
            ngx_write_stderr(
                "Usage: nginx [-?hvVtq] [-s signal] [-c filename] "
                             "[-p prefix] [-g directives]" NGX_LINEFEED
                             NGX_LINEFEED
                "Options:" NGX_LINEFEED
                "  -?,-h         : this help" NGX_LINEFEED
                "  -v            : show version and exit" NGX_LINEFEED
                "  -V            : show version and configure options then exit"
                                   NGX_LINEFEED
                "  -t            : test configuration and exit" NGX_LINEFEED
                "  -q            : suppress non-error messages "
                                   "during configuration testing" NGX_LINEFEED
                "  -s signal     : send signal to a master process: "
                                   "stop, quit, reopen, reload" NGX_LINEFEED
#ifdef NGX_PREFIX
                "  -p prefix     : set prefix path (default: "
                                   NGX_PREFIX ")" NGX_LINEFEED
#else
                "  -p prefix     : set prefix path (default: NONE)" NGX_LINEFEED
#endif
                "  -c filename   : set configuration file (default: "
                                   NGX_CONF_PATH ")" NGX_LINEFEED
                "  -g directives : set global directives out of configuration "
                                   "file" NGX_LINEFEED NGX_LINEFEED
                );
        }

        if (ngx_show_configure) {
            ngx_write_stderr(
#ifdef NGX_COMPILER
                "built by " NGX_COMPILER NGX_LINEFEED
#endif
#if (NGX_SSL)
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
                "TLS SNI support enabled" NGX_LINEFEED
#else
                "TLS SNI support disabled" NGX_LINEFEED
#endif
#endif
                "configure arguments:" NGX_CONFIGURE NGX_LINEFEED);
        }

        if (!ngx_test_config) {
            return 0;
        }
    }

    /* TODO */ ngx_max_sockets = -1;

    //初始化nginx环境的当前时间
    ngx_time_init();

#if (NGX_PCRE)
    ngx_regex_init();
#endif

	//master pid, 获取当前进程ID
    ngx_pid = ngx_getpid();
    // 初始化日志,如打开日志文件
    log = ngx_log_init(ngx_prefix);
    if (log == NULL) {
        return 1;
    }

    /* STUB */
#if (NGX_OPENSSL)
    ngx_ssl_init(log);  //是否开启了ssl,如果开启在这里进行初始化
#endif

    /*
     * init_cycle->log is required for signal handlers and
     * ngx_process_options()
     */

    ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
    init_cycle.log = log;
    ngx_cycle = &init_cycle;
    // 为cycle创建一个1024B的内存池
    init_cycle.pool = ngx_create_pool(1024, log);
    if (init_cycle.pool == NULL) {
        return 1;
    }
    // 保存参数到全局变量中
    if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) {
        return 1;
    }
    // 初始化init_cycle中的一些如: conf_file,prefix,conf_prefix等字段
    if (ngx_process_options(&init_cycle) != NGX_OK) {
        return 1;
    }
    // 初始化系统相关变量,如内存页面大小ngx_pagesize,ngx_cacheline_size,最大连接数ngx_max_sockets等
    if (ngx_os_init(log) != NGX_OK) {  // 这个ngx_os_init在不同操作系统调用不同的函数
        return 1;
    }

    /*
     * ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init()
     */
    // 初始化CRC表,提高效率,以后就不用计算了,直接用
    if (ngx_crc32_table_init() != NGX_OK) {
        return 1;
    }
     // 继承sockets,继承来的socket将会放到init_cycle的listening数组
    if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
        return 1;
    }
    // 计算模块个数,并且设置各个模块顺序(索引)
    ngx_max_module = 0;
    for (i = 0; ngx_modules[i]; i++) {  // 这里面的ngx_modules会有非常多的模块,[ngx_core_module,ngx_errlog_module,ngx_conf_moduel]
        ngx_modules[i]->index = ngx_max_module++;
    }

    // 对ngx_cycle结构进行初始化,这里是nginx启动核心之处!
    cycle = ngx_init_cycle(&init_cycle);
    if (cycle == NULL) {
        if (ngx_test_config) {
            ngx_log_stderr(0, "configuration file %s test failed",
                           init_cycle.conf_file.data);
        }

        return 1;
    }

    if (ngx_test_config) {
        if (!ngx_quiet_mode) {
            ngx_log_stderr(0, "configuration file %s test is successful",
                           cycle->conf_file.data);
        }

        return 0;
    }
    // 检查是否有设置信号处理,如有,进入ngx_signal_process处理
    if (ngx_signal) {
        return ngx_signal_process(cycle, ngx_signal);
    }

    ngx_os_status(cycle->log);

    ngx_cycle = cycle;

    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

    if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) {
        ngx_process = NGX_PROCESS_MASTER;
    }

#if !(NGX_WIN32)

    if (ngx_init_signals(cycle->log) != NGX_OK) {
        return 1;
    }

    if (!ngx_inherited && ccf->daemon) {
        if (ngx_daemon(cycle->log) != NGX_OK) { //如果是daemon模式,本进程变为守护进程
            return 1;
        }

        ngx_daemonized = 1;
    }

    if (ngx_inherited) {
        ngx_daemonized = 1;
    }

#endif
    // 创建进程记录文件
    if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
        return 1;
    }

    if (cycle->log->file->fd != ngx_stderr) {

        if (ngx_set_stderr(cycle->log->file->fd) == NGX_FILE_ERROR) {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
                          ngx_set_stderr_n " failed");
            return 1;
        }
    }

    if (log->file->fd != ngx_stderr) {
        if (ngx_close_file(log->file->fd) == NGX_FILE_ERROR) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          ngx_close_file_n " built-in log failed");
        }
    }

    ngx_use_stderr = 0;

    if (ngx_process == NGX_PROCESS_SINGLE) {
        ngx_single_process_cycle(cycle);   //单进程

    } else {
        ngx_master_process_cycle(cycle);    //多进程,master进程进入这个,这个函数在不同操作系统有不同实现。
    }

    return 0;
}
コード例 #30
0
//创建子进程
ngx_pid_t
ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data,
    char *name, ngx_int_t respawn)
{
    u_long     on;
    ngx_pid_t  pid;
    ngx_int_t  s;

    if (respawn >= 0) {
        s = respawn;
    } else {
		//初始化ngx_processes数组
        for (s = 0; s < ngx_last_process; s++) {
            if (ngx_processes[s].pid == -1) {
                break;
            }
        }

		//进程个数不能大于NGX_MAX_PROCESSES
        if (s == NGX_MAX_PROCESSES) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
                          "no more than %d processes can be spawned",
                          NGX_MAX_PROCESSES);
            return NGX_INVALID_PID;
        }
    }


    if (respawn != NGX_PROCESS_DETACHED) {

        /* Solaris 9 still has no AF_LOCAL */

		//创建用于进程间通信的UNIX域套结字
        if (socketpair(AF_UNIX, SOCK_STREAM, 0, ngx_processes[s].channel) == -1)
        {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "socketpair() failed while spawning \"%s\"", name);
            return NGX_INVALID_PID;
        }

        ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
                       "channel %d:%d",
                       ngx_processes[s].channel[0],
                       ngx_processes[s].channel[1]);

		//将套结字的读写端都设置为非阻塞
        if (ngx_nonblocking(ngx_processes[s].channel[0]) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          ngx_nonblocking_n " failed while spawning \"%s\"",
                          name);
            ngx_close_channel(ngx_processes[s].channel, cycle->log);
            return NGX_INVALID_PID;
        }

        if (ngx_nonblocking(ngx_processes[s].channel[1]) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          ngx_nonblocking_n " failed while spawning \"%s\"",
                          name);
            ngx_close_channel(ngx_processes[s].channel, cycle->log);
            return NGX_INVALID_PID;
        }

        on = 1;
		//以下设置套结字读端为信号驱动,注意我们还没有fork子进程,设置是在master进程中

		//设置FIOASYNC标志(我们必须要这样做),fcntl函数也可以设置,但大多数系统不支持,
		//因此用ioctl来实现
        if (ioctl(ngx_processes[s].channel[0], FIOASYNC, &on) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "ioctl(FIOASYNC) failed while spawning \"%s\"", name);
            ngx_close_channel(ngx_processes[s].channel, cycle->log);
            return NGX_INVALID_PID;
        }

		//设置F_SETOWN标志,将套结字读端和master进程关联起来,当管道有数据的时侯会向该进程
		//发送SIGIO信号
        if (fcntl(ngx_processes[s].channel[0], F_SETOWN, ngx_pid) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "fcntl(F_SETOWN) failed while spawning \"%s\"", name);
            ngx_close_channel(ngx_processes[s].channel, cycle->log);
            return NGX_INVALID_PID;
        }

		//设置管道的FD_CLOEXEC标志
        if (fcntl(ngx_processes[s].channel[0], F_SETFD, FD_CLOEXEC) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "fcntl(FD_CLOEXEC) failed while spawning \"%s\"",
                           name);
            ngx_close_channel(ngx_processes[s].channel, cycle->log);
            return NGX_INVALID_PID;
        }

        if (fcntl(ngx_processes[s].channel[1], F_SETFD, FD_CLOEXEC) == -1) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                          "fcntl(FD_CLOEXEC) failed while spawning \"%s\"",
                           name);
            ngx_close_channel(ngx_processes[s].channel, cycle->log);
            return NGX_INVALID_PID;
        }

        ngx_channel = ngx_processes[s].channel[1];

    } else {
        ngx_processes[s].channel[0] = -1;
        ngx_processes[s].channel[1] = -1;
    }

    ngx_process_slot = s;


    pid = fork();

    switch (pid) {

    case -1: //error
        ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                      "fork() failed while spawning \"%s\"", name);
        ngx_close_channel(ngx_processes[s].channel, cycle->log);
        return NGX_INVALID_PID;

    case 0: //child
        ngx_pid = ngx_getpid();
		//执行我们传递的子进程执行函数
        proc(cycle, data);
        break;

    default: //father
        break;
    }

    ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start %s %P", name, pid);

    ngx_processes[s].pid = pid;
    ngx_processes[s].exited = 0;

    if (respawn >= 0) {
        return pid;
    }

    ngx_processes[s].proc = proc; //设置子进程的执行函数
    ngx_processes[s].data = data; //设置子进程的参数
    ngx_processes[s].name = name; //设置子进程的name
    ngx_processes[s].exiting = 0;

    switch (respawn) {

    case NGX_PROCESS_NORESPAWN:
        ngx_processes[s].respawn = 0;
        ngx_processes[s].just_spawn = 0;
        ngx_processes[s].detached = 0;
        break;

    case NGX_PROCESS_JUST_SPAWN:
        ngx_processes[s].respawn = 0;
        ngx_processes[s].just_spawn = 1;
        ngx_processes[s].detached = 0;
        break;

    case NGX_PROCESS_RESPAWN:
        ngx_processes[s].respawn = 1;
        ngx_processes[s].just_spawn = 0;
        ngx_processes[s].detached = 0;
        break;

    case NGX_PROCESS_JUST_RESPAWN:
        ngx_processes[s].respawn = 1;
        ngx_processes[s].just_spawn = 1;
        ngx_processes[s].detached = 0;
        break;

    case NGX_PROCESS_DETACHED:
        ngx_processes[s].respawn = 0;
        ngx_processes[s].just_spawn = 0;
        ngx_processes[s].detached = 1;
        break;
    }

    if (s == ngx_last_process) {
        ngx_last_process++; //last_proces可以视为子进程个数
    }

    return pid;
}