int main(int argc, char **argv)
{
struct alias *alias;
/* 设置命令的别名
struct alias {
struct list_head list;//命令列表
char *alias;//命令别名
char *path;//命令路径
};
struct list_head {
struct list_head *next;//列表下一个对象
struct list_head *prev;//列表前一个对象
};
*/
bool nofork = false;
/* 进程还没有开始克隆自己 */
char *port;
/* 端口 */
int opt;
/* 一个在for里面使用的普通变量 */
int ch;
/* 一个在while里面使用的普通变量 */
int cur_fd;
/* 保存了"/dev/null"句柄 */
int bound = 0;
/* 绑定的监听端口个数 */
#ifdef HAVE_TLS
/* 当安装了tls插件 */
int n_tls = 0;
/* 如果安装了tls,则不为0 */
const char *tls_key = NULL;
/* ASN.1 server private key file */
const char *tls_crt = NULL;
/* ASN.1 server certificate file */
#endif
BUILD_BUG_ON(sizeof(uh_buf) < PATH_MAX); /* 条件为真,编译报错,uh_buf为4096,path_max一般为260 */
/*
#define __BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
*/
uh_dispatch_add(&cgi_dispatch);
/*
添加cgi调度程序到双向链表
*/
init_defaults_pre();
/*
初始化配置变量
*/
signal(SIGPIPE, SIG_IGN);
/*
函数原型:sig_t signal(int signum,sig_t handler);
功能:设置某一信号的对应动作
第一个参数signum指明了所要处理的信号类型,它可以取除了SIGKILL和SIGSTOP外的任何一种信号。
第二个参数handler描述了与信号关联的动作。
SIGPIPE:在reader中止之后写Pipe的时候发送
SIG_IGN:表示忽略该信号
函数说明:
signal()会依参数signum 指定的信号编号来设置该信号的处理函数。
当指定的信号到达时就会跳转到参数handler指定的函数执行。
当一个信号的信号处理函数执行时,如果进程又接收到了该信号,
该信号会自动被储存而不会中断信号处理函数的执行,直到信号处理函数执行完毕再重新调用相应的处理函数。
但是如果在信号处理函数执行时进程收到了其它类型的信号,该函数的执行就会被中断。
*/
/*
原型:int getopt(int argc,char * const argv[ ],const char * optstring);
功能:用来分析命令行参数。
参数:argc和argv是由main()传递的参数个数和内容。参数optstring则代表欲处理的选项字符串。
函数说明:此函数会返回在argv 中下一个的选项字母,此字母会对应参数optstring 中的字母。
如果选项字符串里的字母后接着冒号“:”,则表示还有相关的参数,全域变量optarg 即会指向此额外参数。
如果getopt()找不到符合的参数则会印出错信息,并将全域变量optopt设为“?”字符,
如果不希望getopt()印出错信息,则只要将全域变量opterr设为0即可。
*/
while (ch = getopt(argc, argv, "A:aC:c:Dd:E:fh:H:I:i:K:k:L:l:m:N:n:p:qRr:Ss:T:t:U:u:Xx:y:") != -1)
{<