Boa源码分析 – 4 – 转意处理

build_needs_escape函数目的是要建立一个位图bitmap,表示哪些字符需要转意。此函数在escape.c中,首先到escape.h中看看。

#include "config.h"

/* Highest character number that can possibly be passed through un-escaped */
#define NEEDS_ESCAPE_BITS 128
//表示128位就行
#ifndef NEEDS_ESCAPE_SHIFT
#define NEEDS_ESCAPE_SHIFT 5     /* 1 << 5 is 32 bits */
#endif

#define NEEDS_ESCAPE_WORD_LENGTH (1<<NEEDS_ESCAPE_SHIFT)
//
#define NEEDS_ESCAPE_INDEX(c) ((c)>>NEEDS_ESCAPE_SHIFT)
//index嘛,表示在_needs_escape中的第几个数上表示

/* Assume variable shift is fast, otherwise this could be a table lookup */
#define NEEDS_ESCAPE_MASK(c)  (1<<((c)&(NEEDS_ESCAPE_WORD_LENGTH - 1)))
//NEEDS_ESCAPE_WORD_LENGTH - 1相当于一个掩码,取c最右边的五bit,然后在把1左移这么多位,就可以通过它获得相应位的状态了

/* Newer compilers could use an inline function.
* This macro works great, as long as you pass unsigned int or unsigned char.
*/
#define needs_escape(c) ((c)>=NEEDS_ESCAPE_BITS || _needs_escape[NEEDS_ESCAPE_INDEX(c)]&NEEDS_ESCAPE_MASK(c))
//实现很简洁。。。
extern unsigned long _needs_escape[(NEEDS_ESCAPE_BITS+NEEDS_ESCAPE_WORD_LENGTH-1)/NEEDS_ESCAPE_WORD_LENGTH];
void build_needs_escape(void);

(更多…)

继续阅读 →

Boa源码分析 – 3 – 三个函数简析

下面看一下boa.c里面的三个函数:create_server_socket, drop_privs和 drop_privs。这三个函数都被声明为static表示,静态函数对普通函数的区别就是他只能在当前文件中可见。

static int create_server_socket(void)
{
int server_s;
server_s = socket(SERVER_AF, SOCK_STREAM, IPPROTO_TCP);
//创建套接字SERVER_AF在compat.h中声明被声明为INET或INET6
if (server_s == -1) {
DIE("unable to create socket");
}
//DIE在defines.h中的宏定义为
//#define DIE(mesg) log_error_mesg(__FILE__, __LINE__, mesg), exit(1)
//__FILE__和__LINE__分别表示当前文件和当前行
//log_error_mesg在log.c中有定义,向标准输出输出错误信息

/* server socket is nonblocking */
if (set_nonblock_fd(server_s) == -1) {
DIE("fcntl: unable to set server socket to nonblocking");
}//把套接字设定成非阻塞的,set_nonblock_fd在defines.h中为宏替代real_set_nonblock_fd(在util.c中定义)

/* close server socket on exec so cgi's can't write to it */
if (fcntl(server_s, F_SETFD, 1) == -1) {
DIE("can't set close-on-exec on server socket!");
}//将文件描述符标记设定为1,当执行exec族函数时关闭套接字

(更多…)

继续阅读 →

Boa源码分析 – 2 – boa.c流程

下面来看看boa.c吧

/* set umask to u+rw, u-x, go-rwx */
c = umask(~0600);
if (c == -1) {
perror("umask");
exit(1);
}
devnullfd = open("/dev/null", 0);
/* make STDIN and STDOUT point to /dev/null */
if (devnullfd == -1) {
DIE("can't open /dev/null");
}
if (dup2(devnullfd, STDIN_FILENO) == -1) {
DIE("can't dup2 /dev/null to STDIN_FILENO");
}
if (dup2(devnullfd, STDOUT_FILENO) == -1) {
DIE("can't dup2 /dev/null to STDOUT_FILENO");
}

这里设定了权限掩码为~600,也就是生成文件权限为rw——-,然后打开/dev/null,它相当于一个黑洞,输入任何东西都会丢失,读取也什么都读取不到,因为服务器进程是在守护进程,所以将标准输入输出定向到/dev/null。下面看getopt:
(更多…)

继续阅读 →

Boa源码分析 – 1 – Makefile

boa是一个小型的webserver,设计目标是速度和安全,虽然这个项目已经很多年没有更新了,但是对于初学linux编程,网络编程的同学来说。。还是很有价值的。boa的实际代码量只有7000+(去掉autotools自动生成的东西),初看压力不大。当然还有一些适合学习的开源项目,如thttpd(也是一个http server,代码12000+行),redis(key-value存储系统,和Memcached类似,里面貌似有好多数据结构?两万多行)和coreutils (常用linux命令源码,什么cd,chmod,cp等等),还有好多,github和sourceforge上有很丰富资源。。

直接入题吧,boa也用到了Autotools,但是我实在是搞不清楚autotools的几个命令是怎么组织的。。干脆直接./configure ,开始分析Makefile。
(更多…)

继续阅读 →