1.日志
/*****************************************
包含头文件: #include <syslog.h>
函数原型: void openlog(const char* ident,int option,int facility);
void syslog(int priority,const char* format,….);
void closelog(void);
int setlogmask(int maskpri);
返回值:前日志记录优先级屏蔽字值
OPTIONS:
LOG_PID 加上进程标识符
LOG_CON如果消息无法记录日志文件就发到控制台
LOG_NDELAY 第一次调用syslog立即打开日志功能
LOG_WAIT 不等待将消息记入日志可能已创建的子进程
LOG_ODELAY 第一条日志消息记录打开之前延迟打开至syslogd守护进程的连接
LOG_PERROR 写入日志之外还写入标准出错
PRIORITY
LOG_ERRERG 紧急(最高优先级)
LOG_ALERT 必须立即恢复的情况
LOG_CRIT 严重情况(如硬件设备出错)
LOG_ERR 出错情况
LOG_WARNING 警告情况
LOG_NOTICE 正常但重要的情况
LOG_INFO 信息性消息
LOG_DEBUG 调试消息
*****************************************/
vi 13.1.c
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
int main()
{
char* buf = "not exist";
FILE* fp;
fp = fopen(buf,"r");
if (!fp)
{
syslog(LOG_ERR | LOG_USER,"%m\n");
}
return 0;
}
2.守护进程
1.初始化守护进程
1.设置特定文件创建屏蔽字
2.调用fork 退出父进程
3.调用setsid使调用进程成为会话首进程 fork 使子进程无控制终端 退出调用进程
4.屏蔽可能唤起控制台的信号
5.关闭不再需要的文件描述符
6.将当前工作目录更改为根目录
7.进行日志管理
vi 13.2.c
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/resource.h>
#include <syslog.h>
#include <fcntl.h>
#include <sys/stat.h>
void daemonize(const char* cmd)
{
struct rlimit rl;
struct sigaction sa;
pid_t pid;
int fd0,fd1,fd2;
umask(0);
if (getrlimit(RLIMIT_NOFILE,&rl) < 0)
{
printf("getrlimit error\n");
exit(0);
}
if ((pid = fork()) < 0)
{
printf("fork error\n");
exit(0);
}
else if (pid != 0)
exit(0);
setsid();
sa.sa_handler = SIG_IGN;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGHUP,&sa,NULL) < 0)
{
printf("sigaction error\n");
exit(0);
}
if ((pid = fork()) < 0)
{
printf("fork error\n");
exit(0);
}
else if (pid != 0)
exit(0);
if (chdir("/") < 0)
{
printf("chdir error\n");
exit(0);
}
if(rl.rlim_max == RLIM_INFINITY)
rl.rlim_max = 1024;
for (int i = 0; i < rl.rlim_max; ++i)
close(i);
umask(0);
fd0 = open("/dev/null",O_RDWR);
fd1 = dup(0);
fd2 = dup(0);
openlog(cmd,LOG_CONS,LOG_DAEMON);
if (fd0 != 0 || fd1 != 1 || fd2 != 2)
{
syslog(LOG_ERR,"unexpect file descripttors %d %d %d",fd0,fd1,fd2);
exit(1);
}
}
int main()
{
daemonize("13.2.out");
sleep(1000);
return 0;
}
3.守护进程配置文件及单副本运行
include <sys/resource.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <syslog.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#define LOCKFILE "/var/run/mydaemon.conf"
#define LOCKMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
sigset_t mask;
int lockfile(int fd)
{
struct flock fl;
fl.l_type = F_RDLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
return fcntl(fd,F_SETLK,&fl);
}
int single_run()
{
int fd = open(LOCKFILE,O_RDWR | O_CREAT,LOCKMODE);
if (fd < 0)
{
syslog(LOG_ERR,"%s %d\n",strerror(errno),fd);
exit(1);
}
if (lockfile(fd) < 0)
{
syslog(LOG_ERR,"%s\n",strerror(errno));
return -1;
}
ftruncate(fd,0);
char buf[100];
sprintf(buf,"PPID: %ld PID: %ld",(long)getpid(),(long)getppid());
write(fd,buf,strlen(buf) + 1);
return 0;
}
void* signal_handler(void* arg)
{
int err,signo;
for (; ;)
{
sigwait(&mask,&signo);
switch(signo)
{
case SIGHUP:
syslog(LOG_ERR,"try hup\n");
break;
case SIGTERM:
exit(0);
default:
syslog(LOG_ERR,"unexpected signal\n");
}
}
}
void mydaemon(const char* cmd)
{
struct rlimit rl;
struct sigaction sa;
if (getrlimit(RLIMIT_NOFILE,&rl) < 0)
{
syslog(LOG_ERR,"getrlimit error\n");
exit(1);
}
umask(0);
pid_t pid;
if ((pid = fork()) < 0)
{
syslog(LOG_ERR,"first fork error\n");
exit(1);
}else if (pid > 0)
exit(0);
setsid();
sa.sa_handler = SIG_IGN;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGHUP,&sa,NULL) < 0)
{
syslog(LOG_ERR,"first sigaction error\n");
exit(1);
}
if ((pid = fork()) < 0)
{
syslog(LOG_ERR,"second fork error\n");
exit(1);
}else if (pid > 0)
exit(0);
if (chdir("/") < 0)
{
syslog(LOG_ERR,"chdir error\n");
exit(1);
}
if (rl.rlim_max == RLIM_INFINITY)
rl.rlim_max = 1024;
for (int i = 0; i < rl.rlim_max; ++i)
close(i);
int fd0,fd1,fd2;
fd0 = open("/dev/null",O_RDWR);
fd1 = dup(0);
fd2 = dup(0);
openlog(cmd,LOG_CONS,LOG_DAEMON);
if (fd0 != 0 || fd1 != 1 || fd2 != 2)
{
syslog(LOG_ERR,"unexpected file destription error\n");
exit(1);
}
}
int main()
{
struct sigaction sa;
mydaemon("mydaemond");
if (single_run() < 0)
{
syslog(LOG_ERR,"dummy has been run\n");
exit(1);
}
sa.sa_handler = SIG_DFL;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGHUP,&sa,NULL) < 0)
{
syslog(LOG_ERR,"sigaction error\n");
exit(1);
}
sigfillset(&mask);
if (pthread_sigmask(SIG_SETMASK,&mask,NULL) != 0)
{
syslog(LOG_ERR,"sigprocmask error\n");
exit(1);
}
pthread_t tid;
if (pthread_create(&tid,NULL,signal_handler,NULL) != 0)
{
syslog(LOG_ERR,"pthread_create error\n");
exit(1);
}
while (1)
sleep(100);
return 0;
}