您的位置:首页 > 产品设计 > UI/UE

《APUE》chapter 13 Deamon Process 学习笔记(加上自己的代码)

2014-04-07 20:05 411 查看

Deamon Process 

Because they don’t have  a  controlling  terminal,  we  say  that  they  run  in  the  background.

Daemon Characteristics

some  common  system  daemons  and  how  they  relate  to  the  concepts  of process groups

linux 下面我用root权限获取的信息:

ps -efj


UID        PID  PPID  PGID   SID  C STIME TTY          TIME CMD

root         1     0     1     1  0 13:08 ?        00:00:03 /sbin/init

root         2     0     0     0  0 13:08 ?        00:00:00 [kthreadd]

root         3     2     0     0  0 13:08 ?        00:00:01 [ksoftirqd/0]

root         5     2     0     0  0 13:08 ?        00:00:00 [kworker/0:0H]

root         6     2     0     0  0 13:08 ?        00:00:00 [kworker/u:0]

root         7     2     0     0  0 13:08 ?        00:00:00 [kworker/u:0H]

root         8     2     0     0  0 13:08 ?        00:00:00 [migration/0]

root         9     2     0     0  0 13:08 ?        00:00:00 [rcu_bh]

root        10     2     0     0  0 13:08 ?        00:00:03 [rcu_sched]

root        11     2     0     0  0 13:08 ?        00:00:00 [watchdog/0]

root        12     2     0     0  0 13:08 ?        00:00:06 [watchdog/1]

root        13     2     0     0  0 13:08 ?        00:00:00 [ksoftirqd/1]

root        14     2     0     0  0 13:08 ?        00:00:00 [migration/1]

........

........

jasonleaster  2093  2028  2028  2028  0 13:12 ?        00:00:02 /usr/lib/gnome-settings-daemon/gnome-settings-daemon

jasonleaster  2105     1  2104  2104  0 13:12 ?        00:00:00 /usr/bin/pulseaudio --start --log-target=syslog

jasonleaster  2112     1  2077  2077  0 13:12 ?        00:00:00 /usr/lib/gvfs/gvfsd

       The system processes you see will depend on the operating system implementation. Anything with a parent process ID of 0 is usually a kernel process started as part of the system  bootstrap  procedure. 

        Note  that  most  of  the  daemons  run  with  superuser  (root)  privileges.Most of the user-level daemons are process group leaders and session leaders, and
 are the  only  processes  in  their  process  group  and  session. (The  one  exception  is rsyslogd .)  Finally,note that the parent of the user-level daemons is the init process.

 Coding Rules

1.  Call umask to set the file mode creation mask to a known value, usually 0. The inherited  file  mode  creation  mask  could  be  set  to  deny  certain  permissions.  

2.  Call fork and  have  the  parent exit. 

3.  Call  setsid  to create a new session.

4.  Change the  current  working  directory  to  the  root  directory . 

5.  Unneeded file  descriptors  should  be  closed.  

6.  Some daemons  open  file  descriptors  0,  1,  and  2  to /dev/null so  that  any library routines that try to read from standard input or write to standard output or
standard error will have no effect.   

Error  Logging

          One  problem  a  daemon  has  is  how  to  handle  error  messages. A central daemon error-logging facility is required.



1.  Kernel ro utines  can  call  thelog function.  These messages  can  be  read  by  any user process that opens and reads the /dev/klog device.   

2.  Most user  processes  (daemons)  call  the syslog(3) function  to  generate  log messages.   

3.  A user process on this host, or on some other host that is connected to this host by  a  TCP/IP  network,  can  send  log  messages  to  UDP  port  514.  

Our interface to this facility is through the syslog function.

#include <syslog.h>
void openlog(const char *ident,int option ,int facility );
void syslog(intpriority,const char *format ,...);
void closelog(void);
int setlogmask(int maskpri);
Returns: previous log priority mask value


              Calling openlog is optional. If it’s not called, the first time syslog is called,openlog is called automatically . Callingcloselog is also optional —it just
closes the descriptor that was being used to communicate with thesyslogd daemon.



 

没有terminal联系起来,daemon最多的联系就是logfile了。这个时候就是分析各种各样的log file...

linux下各种各样的log file

jasonleaster@ubuntu:/var/log$ ls

alternatives.log       apt            ConsoleKit    dpkg.log.2.gz   kern.log.3.gz          pm-powersave.log.4.gz  udev

alternatives.log.1     auth.log       cups          dpkg.log.3.gz   kern.log.4.gz          samba                  ufw.log

alternatives.log.2.gz  auth.log.1     dist-upgrade  dpkg.log.4.gz   lastlog                speech-dispatcher      unattended-upgrades

apport.log               auth.log.2.gz  dmesg         faillog         lightdm                syslog                 upstart

apport.log.1            auth.log.3.gz  dmesg.0       fontconfig.log  mail.err               syslog.1               vmware-tools-upgrader.log

apport.log.2.gz        auth.log.4.gz  dmesg.1.gz    fsck            mail.log               syslog.2.gz            wtmp

apport.log.3.gz        boot           dmesg.2.gz    hp              news                   syslog.3.gz            wtmp.1

apport.log.4.gz        boot.log       dmesg.3.gz    installer       pm-powersave.log       syslog.4.gz            Xorg.0.log

apport.log.5.gz        bootstrap.log  dmesg.4.gz    kern.log        pm-powersave.log.1     syslog.5.gz            Xorg.0.log.old

apport.log.6.gz        btmp           dpkg.log      kern.log.1      pm-powersave.log.2.gz  syslog.6.gz            Xorg.1.log

apport.log.7.gz        btmp.1         dpkg.log.1    kern.log.2.gz   pm-powersave.log.3.gz  syslog.7.gz            Xorg.1.log.old

表示我木有找到/var/log/messages....

日志文件系统不熟悉。。。感觉daemon学的有点。。。不懂。。。几乎就写不出demo出来。。。

待更新吧。。。待俺功力精进之后。。。。

update: 2014.05.10

#include <syslog.h>
#include <fcntl.h>
#include <sys/resource.h>
#include <stdio.h>
#include <stdlib.h>
#include <myerr.h>

void daemonize(const char * cmd)
{
int     i,fd0,fd1,fd2;
pid_t   pid;
struct  rlimit   rl;
struct  sigaction sa;

umask(0);

if(getrlimit(RLIMIT_NOFILE,&rl) < 0)
{
err_quit("%s: can't get file limit",cmd);
}

if((pid = fork()) < 0)
{
err_quit("%s : can't fork",cmd);
}
else if(pid != 0)
{
exit(0);
} //第一次fork,然后杀掉parent process,得到child process,这时候这个child process还在原来的process group里面。这个grp成为了孤儿进程组!!

setsid(); //由于此时child process所在的进程组它不是process leader,leader是他原来还活着的parent process(此时parent是 init进程),于是它可以成为session leader

sa.sa_handler = SIG_IGN; //成为orphaned group,会被发送SIGHUP和SIGCONT信号(由0.12内核代码阅读所得,可能和现在的3.0的略有不同)
sigemptyset(&sa.sa_mask); //统统忽略掉这两个信号,防止这个即将称为deamon进程被杀
sa.sa_flags = 0;
if((sigaction(SIGHUP,&sa,NULL)) < 0)
{
err_quit("%s can't fork\n",cmd);
}

if((pid = fork()) < 0) //第二次fork是为了杀死原来的进程,创造出新child proces,新的child proces不是session leader,于是不可能再与terminal有联系!That's all!
{
err_quit("%s : can't fork",cmd);
}
else if (pid != 0)
{
exit(0);
}

if(chdir("/")  <  0) //切换当前工作目录
{
err_quit("%s can't change dirctory to /\n");
}

if(rl.rlim_max == RLIM_INFINITY)
{
rl.rlim_max = 1024;
}

for(i = 0; i < rl.rlim_max;i++)
{
close(i);
}

fd0 = open("/dev/null",O_RDWR); //因为close(i)关闭了所有的file descriptor,于是这时候open打开的/dev/null的fd是0,fd 0 1 2
// 都定向到null,保证不会有信息通过 fd 0 1 2输入输出到标准输入输出错误
fd1 = dup(0);
fd2 = dup(0);

openlog(cmd,LOG_CONS,LOG_DAEMON); //打开syslog,把cmd字符串写进去,这里cmd是helloworld,可以在syslog里面找到,见下面的图

if(fd0  != 0 || fd1 != 1 || fd2 != 2)
{
syslog(LOG_ERR,"unexpected file deacriptors %d %d %d\n",fd0,fd1,fd2);
exit(1);
}
}

int main()
{
daemonize("hello world!\n");
return 0;
}


这里如果把if判断条件改一下,就可以调用syslog函数,把参数写入syslog文件
if(fd0 == 0 || fd1 != 1 || fd2 != 2)



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: