文档章节

boa阅读笔记3

开源中国精神科主任
 开源中国精神科主任
发布于 2014/10/03 15:23
字数 648
阅读 11
收藏 0
void open_logs(void)
{
    int error_log;

    /* if error_log_name is set, dup2 stderr to it */
    /* otherwise, leave stderr alone */
    /* we don't want to tie stderr to /dev/null */
    if (error_log_name) {
        /* open the log file */
        if (!(error_log = open_gen_fd(error_log_name))) {
            DIE("unable to open error log");
        }

        /* redirect stderr to error_log */
        if (dup2(error_log, STDERR_FILENO) == -1) {
            DIE("unable to dup2 the error log");
        }
        close(error_log);
    }

    /* set the close-on-exec to true */
    //当使用exec时关闭stderr,防止其他程序写stderr
    if (fcntl(STDERR_FILENO, F_SETFD, 1) == -1) {
        DIE("unable to fcntl the error log");
    }

    if (access_log_name) {//权限日志
        /* Used the "a" flag with fopen, but fopen_gen_fd builds that in
         * implicitly when used as a file, and "a" is incompatible with
         * pipes and network sockets. */
        if (!(access_log = fopen_gen_fd(access_log_name, "w"))) {
            int errno_save = errno;
            fprintf(stderr, "Cannot open %s for logging: ",
                    access_log_name);
            errno = errno_save;
            perror("logfile open");
            exit(errno);
        }
        /* line buffer the access log */
#ifdef SETVBUF_REVERSED
        setvbuf(access_log, _IOLBF, (char *) NULL, 0);
#else
        setvbuf(access_log, (char *) NULL, _IOLBF, 0);
#endif
    } else
        access_log = NULL;

    if (cgi_log_name) {//cgi日志
        cgi_log_fd = open_gen_fd(cgi_log_name);
        if (cgi_log_fd == -1) {
            WARN("open cgi_log");
            free(cgi_log_name);
            cgi_log_name = NULL;
            cgi_log_fd = 0;
        } else {
            if (fcntl(cgi_log_fd, F_SETFD, 1) == -1) {//当exec时关闭cgi_log
                WARN("unable to set close-on-exec flag for cgi_log");
                close(cgi_log_fd);
                cgi_log_fd = 0;
                free(cgi_log_name);
                cgi_log_name = NULL;
            }
        }
    }
}

open_logs完成了程序所需日志的打开、重定向和设置,并防止新建进程对日志的干扰。

完成 一系列的环境初始化后,接下来就是创建监听socket了。

    server_s = create_server_socket();

static int create_server_socket(void)
{
    int server_s;
    
    server_s = socket(SERVER_AF, SOCK_STREAM, IPPROTO_TCP); //创建TCP协议的socket
    if (server_s == -1) {
        DIE("unable to create socket");
    }

    /* server socket is nonblocking */
    if (set_nonblock_fd(server_s) == -1) {//设置文件描述符为无阻塞模式
        DIE("fcntl: unable to set server socket to nonblocking");
    }

    /* close server socket on exec so cgi's can't write to it */
    if (fcntl(server_s, F_SETFD, 1) == -1) {      //FD_CLOEXEC
        DIE("can't set close-on-exec on server socket!");
    }

    /* reuse socket addr */
    if ((setsockopt(server_s, SOL_SOCKET, SO_REUSEADDR, (void *) &sock_opt,
                    sizeof (sock_opt))) == -1) {
        DIE("setsockopt");
    }

    /* internet family-specific code encapsulated in bind_server()  */
    if (bind_server(server_s, server_ip) == -1) {//实现了ipv4和ipv6的定制绑定
        DIE("unable to bind");
    }

    /* listen: large number just in case your kernel is nicely tweaked */
    if (listen(server_s, backlog) == -1) {//监听
        DIE("unable to listen");
    }
    return server_s;
}

一个标准的socket创建流程后,服务端口已经成功被程序监听。

接下来是对信号处理函数进行设置。

    init_signals();
void init_signals(void)
{
    struct sigaction sa;

    sa.sa_flags = 0;
    //设置在信号处理函数中需要屏蔽的信号
    sigemptyset(&sa.sa_mask); //清空sa_mask
    sigaddset(&sa.sa_mask, SIGSEGV);
    sigaddset(&sa.sa_mask, SIGBUS);
    sigaddset(&sa.sa_mask, SIGTERM);
    sigaddset(&sa.sa_mask, SIGHUP);
    sigaddset(&sa.sa_mask, SIGINT);
    sigaddset(&sa.sa_mask, SIGPIPE);
    sigaddset(&sa.sa_mask, SIGCHLD);
    sigaddset(&sa.sa_mask, SIGALRM);
    sigaddset(&sa.sa_mask, SIGUSR1);
    sigaddset(&sa.sa_mask, SIGUSR2);
    //设置信号处理函数
    sa.sa_handler = sigsegv;
    sigaction(SIGSEGV, &sa, NULL);

    sa.sa_handler = sigbus;
    sigaction(SIGBUS, &sa, NULL);

    sa.sa_handler = sigterm;
    sigaction(SIGTERM, &sa, NULL);

    sa.sa_handler = sighup;
    sigaction(SIGHUP, &sa, NULL);

    sa.sa_handler = sigint;
    sigaction(SIGINT, &sa, NULL);

    sa.sa_handler = SIG_IGN;
    sigaction(SIGPIPE, &sa, NULL);

    sa.sa_handler = sigchld;
    sigaction(SIGCHLD, &sa, NULL);

    sa.sa_handler = sigalrm;
    sigaction(SIGALRM, &sa, NULL);

    sa.sa_handler = SIG_IGN;
    sigaction(SIGUSR1, &sa, NULL);

    sa.sa_handler = SIG_IGN;
    sigaction(SIGUSR2, &sa, NULL);
}

完成了信号的设置,离程序真正开始工作又近了一步,下次再接着分析下面几步。


© 著作权归作者所有

上一篇: boa阅读笔记4
下一篇: boa阅读笔记2
开源中国精神科主任
粉丝 1
博文 18
码字总数 26787
作品 0
杭州
私信 提问
嵌入式Web服务器移植

第一步 Boa程序的移植 1、下载Boa源码 下载地址: http://www.boa.org/, 或者 http://sourceforge.net 最新发行版本: 0.94.13 下载 boa-0.94.13.tar.gz,注意:从boa上下载的是boa-0.94.13...

晨曦之光
2012/03/09
52
0
SylixOS移植Boa服务器

1. Boa简介 Boa是一种非常小巧的Web服务器,其可执行代码只有大约60KB左右。作为一种单任务Web服务器,Boa只能依次完成用户的请求,而不会fork出新的进程来处理并发连接请求。但Boa支持CGI,...

遗忘丶彻底
2017/07/10
0
0
Python学习札记(2)——搭建Boa-constructor

一、Boa-constructor是什么 看看来自己百度的解释:Boa Constructor是一个跨平台的Python集成开发环境和wxPython图形用户界面构建器。它提供了可视化方式的框架(窗口) 的创建 和处理、对象...

东方卯
2014/03/04
0
2
boa与cgic库写cgi简介

嵌入式 WEB 服务器 BOA 和 CGI 一、嵌入式 WEB 服务器 BOA 简介 嵌入式 WEB 服务器常见的有: boa lighttpd shttpd thttpd mathopd minihttpd appweb goahead 随着 Internet 技术的兴起,在嵌...

唧唧帝
2014/01/15
0
0
使用cx_Freeze打包wxpython和boa-constructor开发的应用

零、准备工作: 单就打包python写的应用来说,cx_Freeze就够了。 目标: 用wxPython库和Boa集成开发环境构建个有图形界面的程序,然后把这软件用cx_Freeze打包为exe。 这个程序只有一个按钮,...

LiShixi
2013/08/05
0
2

没有更多内容

加载失败,请刷新页面

加载更多

typescript 接口 函数类型 可索引类型

函数类型 可索引类型 数字索引签名 字符串索引签名 数字索引签名返回值 必须是 字符串索引签名返回值的子集 只读索引签名

lilugirl
今天
3
0
Oracle SQL语法实例合集

如需转载请注明出处https://my.oschina.net/feistel/blog/3052024 目的:迅速激活Oracle SQL 参考:《Oracle从入门到精通》 ------------------------------------------------------------......

LoSingSang
今天
2
0
增加 PostgreSQL 服务进程的最大打开文件数

https://serverfault.com/questions/628610/increasing-nproc-for-processes-launched-by-systemd-on-centos-7 要在systemd的配置里加才行...

helloclia
今天
2
0
组合模式在商品分类列表中的应用

在所有的树形结构中最适合的设计模式就是组合模式,我们看看常用商品分类中如何使用。 先定义一个树形结构的商品接口 public interface TreeProduct { List<TreeProduct> allProducts(...

算法之名
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部