UNP第13章——守护进程
1. 守护进程的启动方法
(1)系统初始化脚本启动,在系统启动阶段,按照如/etc目录或/etc/rc开头的目录中的某些脚本启动,这些守护进程一开始就有超级用户权限。如inetd,cron,Web服务器
(2)由inetd超级服务器启动。inetd监听网络请求(FTP,Telnet..),每当一个请求到达时,启动相应实际服务器。
(3)cron守护进程启动。cron按照规则定期执行一些程序。
(4)at命令。at命令指定某个时刻启动程序,这些程序由cron启动。
(5)用户终端启动,这需要守护进程亲自脱离与控制终端的关联。
2.1 syslogd守护进程
由于守护进程没有控制终端,所以无法向stderr输出消息,因此使用syslogd记录消息。
syslogd由系统初始化脚本启动,syslogd启动时完成以下步骤:
(1)读取配置文件,如/etc/syslog.conf以指定可能收取的消息应该如何处理。
(2)创建一个Unix域套接字,给它绑定到/var/run/log 或 /var/log
(3)创建一个UDP套接字,绑定514端口
(4)打开/dev/klog,从该设备获得内核的任何出错信息。
之后进行循环:调用select监听3个文件描述符(上面2,3,4步骤获得),描述符可读,则读之,并将消息写入日志。
如果收到SIGHUP则重新读取配置文件。
2.2 向syslogd发消息
(1)应用创建Unix套接字,绑定与syslogd相同的路径。
(2)创建UDP套接字,向514端口发信息(新的syslogd禁止了UDP套接字,原因是由于UDP套接字缓冲被恶意写满,导致拒绝服务攻击)
(3)调用syslog函数,该函数封装了使用Unix域套接字的方法。
2.3 syslog函数
void syslog(int priority, const char *format, ...);
priority由 level 和 facility 两者组合,format 是格式化串,增加了 %m(它被替换成 errno 对应的错误消息)
level 默认为LOG_NOTICE
facility 指定发送消息的进程类型
举例进程可以调用
syslog(LOG_INFO | LOG_LOCAL2, "rename (%s, %s) : %m", file1, file2);
/etc/syslog.conf可以这样指定
kern.* /dev/console
local2.info /var/log/cisco.log
这样来自 local2 设施的 info 消息就会记录到 /var/log/cisco.log
syslog 首次调用时创建Unix域套接字,后调用connect连接路径(/var/run/log),套接字一直打开,直到进程终止。
2.4 openlog 和 closelog
void openlog(const char *ident, int options, int facility);
void closelog(void);
openlog 在首次调用syslog前调用,closelog在不再发送日志消息时调用。
ident 指定 syslog每个日志消息首部的字符串,通常用 程序名
options 参数有以下组合
facility 为没有指定设施的syslog调用设置一个默认的值,这样之后的syslog只需要指定level。
openlog 调用时,通常不会创建Unix域套接字,套接字直到首次调用syslog才打开。
2. daemon_init
#define MAXFD 64 extern int daemon_proc; /* defined in error.c */ int
daemon_init(const char *pname, int facility)
{
int i;
pid_t pid; if ( (pid = Fork()) < 0)
return (-1);
else if (pid)
_exit(0); /* parent terminates */ /* child 1 continues... */ if (setsid() < 0) /* become session leader */
return (-1); Signal(SIGHUP, SIG_IGN);
if ( (pid = Fork()) < 0)
return (-1);
else if (pid)
_exit(0); /* child 1 terminates */ /* child 2 continues... */ daemon_proc = 1; /* for err_XXX() functions */ chdir("/"); /* change working directory */ /* close off file descriptors */
for (i = 0; i < MAXFD; i++)
close(i); /* redirect stdin, stdout, and stderr to /dev/null */
open("/dev/null", O_RDONLY);
open("/dev/null", O_RDWR);
open("/dev/null", O_RDWR); openlog(pname, LOG_PID, facility); return (0); /* success */
}
(1)fork
调用fork,并终止父进程,子进程在后台运行,是为了shell认为命令已经执行完成,从而命令交出控制台。
(2)setsid
创建新会话,保证子进程为会话头进程和进程组头进程,从而不再有控制终端。
(3)忽略SIGHUP,并再次fork
为了确定程序不会再获得控制终端,所以需要进程不能是会话进程的头进程。
因为如果将来进程打开控制终端,该终端会自动成为会话头进程的控制终端。
当会话头进程终止时,会向会话的所有子进程发送SIGHUP,所以要忽略SIGHUP。
(4)改变工作目录
守护进程需要改变工作目录到其真正的工作的地方。
原因是,守护进程可能在文件系统任何地方被启动,如果仍然在其中,那么该文件系统就无法卸载。
(5)关闭所有打开的文件描述符
关闭守护进程从执行的它的进程(通常是shell)继承来的所有打开的描述符
(6)将stdin,stdout,stderr重定向到/dev/null
这有两个好处,
保证这些常用描述符是打开的,针对他们的系统调用read返回EOF,write则由内核丢弃所有数据,因此守护进程不会因为调用这些程序而失败。
避免打开其他描述符从0,1,2开始,否则perror会将数据发到错误的地方。
(7)syslogd处理错误
守护进程与信号
守护进程没有控制终端,所以它不会收到SIGHUP,可以将SIGHUP作为通知信号,比如通知配置文件已经修改。
同样守护进程也不会收到SIGINT 和 SIGWINCH 信号,也可以安全的将这些信号作为通知信号。
UNP第13章——守护进程的更多相关文章
- APUE读书笔记-第13章-守护进程
第13章 守护进程 13.1 引言 *守护进程也称精灵进程(daemon)是生存期较长的一种进程.它们常常在系统自举时启动,仅在系统关闭时才终止.因为它们没有控制终端,所以说它们是在后台运行的.UNI ...
- UNP学习第13章 守护进程和inetd超级服务器
Unix系统中的syslogd守护进程通常由某个系统初始化脚本启动,而且在系统工作期间一直运行. 源自Berkeley的syslogd实现在启动时执行以下步骤. (1)读取配置文件.通常为/etc/s ...
- Unix网络编程代码 第13章 守护进程和inetd超级服务器
1. 概述 守护进程是在后台运行且不与任何控制终端关联的进程.unix系统通常有很多守护进程在后台运行,执行不同的管理任务. 守护进程没有控制终端通常源于它们由系统初始化脚本启动.然而守护进程也 ...
- UNIX环境高级编程 第13章 守护进程
守护进程daemon是一种生存周期很长的进程.它们通常在系统引导时启动,在系统关闭时终止.守护进程是没有终端的,它们一直在后台运行. 守护进程的特征 在Linux系统中,可以通过命令 ps -efj ...
- 《Unix环境高级编程》读书笔记 第13章-守护进程
1. 引言 守护进程是生存期长的一种进程.它们常常在系统引导装入时启动,仅在系统关闭时才终止.它们没有控制终端,在后台运行. 本章说明守护进程结构.如何编写守护进程程序.守护进程如何报告出错情况. 2 ...
- 《Unix 网络编程》13:守护进程和 inetd 超级服务器
守护进程和 inetd 超级服务器 ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ★ ...
- UNP学习笔记(第十三章 守护进程和inetd超级服务器)
关于守护进程可以查看apue的笔记 http://www.cnblogs.com/runnyu/p/4645046.html daemon_init函数 下面给出名为daemon_init函数,通过调 ...
- 《APUE》读书笔记第十三章-守护进程
守护进程 守护进程是生存期较长的一种进程,它们常常在系统自举时启动,仅在系统关闭时才终止.因为它们没有控制终端,所以说它们是在后台运行的.UNIX系统由很多守护进程,它们执行日常事务活动. 本章主要介 ...
- apue学习笔记(第十三章 守护进程)
本章将说明守护进程结构,以及如何编写守护进程程序. 守护进程,也就是通常说的Daemon进程,是Unix中的后台服务进程.它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理 ...
随机推荐
- 云服务器、euleros系统自动断开连接解决方案
我这里的云服务器,网上查的修改sshd.config文件并不有效 我提供另一种方法解决这个问题: vim /etc/profile 再最底部新增 export TMOUT=6000 #6000代表60 ...
- pytest学习纪要123-针对经常用到的内容详实记录
pytest123 本文主要参考:https://www.cnblogs.com/yoyoketang/tag/pytest 如有侵权,请站内联系我 目录 pytest123 1.setup和tear ...
- linux(centos8):firewalld的运行时日志配置
一,firewalld配置日志的用途: 在生产环境中,firewalld的默认配置是不记录日志 我们通过日志记录下防火墙过滤时拒绝的非法ip, 可以主动把这些有攻击性的ip加入到黑名单, 防患于未然 ...
- 第二十四章 IPtables防火墙
一.iptables防火墙基本概述 1.应用场景 1.主机安全2.端口转发/ip转发3.内部共享上网 2.iptables工作流程 1.配置防火墙规则可以添加在下面,也可以添加在前面,是有顺序的2.匹 ...
- springboot入门系列(三):SpringBoot教程之RabbitMQ示例
SpringBoot教程之RabbitMQ示例 SpringBoot框架已经提供了RabbitMQ的使用jar包,开发人员在使用RabbitMQ的时候只需要引用jar包简单的配置一下就可以使用Rabb ...
- python自测100题
如果你在寻找python工作,那你的面试可能会涉及Python相关的问题. 通过对网络资料的收集整理,本文列出了100道python的面试题以及答案,你可以根据需求阅读测试.如果你看了还是不懂可以加我 ...
- pybind11和numpy进行交互
使用一个遵循buffer protocol的对象就可以和numpy交互了. 这个buffer_protocol要有哪些东西呢? 要有如下接口: struct buffer_info { void ...
- Pytest学习(四) - fixture的使用
前言 写这篇文章,整体还是比较坎坷的,我发现有知识断层,理解再整理写出来,还真的有些难. 作为java党硬磕Python,虽然对我而言是常事了(因为我比较爱折腾,哈哈),但这并不能影响我的热情. 执念 ...
- java 常用快捷键及命令积累
ctl + shift + o--->导入所需包,删掉没有被引用的包 ctl + / --->添加多行注释 ctl + \--->删除多行注释
- zctf2016_note2:一个隐蔽的漏洞点挖掘
代码量挺大的,逆起来有难度 功能挺全,啥都有 main函数 add函数,有heaparray并且无pie保护,考虑unlink show函数,可以泄漏地址用 edit函数,有两种edit方式 dele ...