#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
void deamon_mode()
{
pid_t pid;
//创建子进程,父进程退出
if((pid = fork()) < 0)
{
perror("Fail fork");
exit(EXIT_FAILURE);
}
if(pid > 0)
{
exit(EXIT_SUCCESS);
}
//创建新会话期
if(setsid() < 0)
{
perror("Fail to setsid");
exit(EXIT_FAILURE);
}
//改变工作目录为"/"
chdir("/");
//重设文件掩码
umask(0);
//关闭不需要的文件描述符
close(0);
close(1);
close(2);
return ;
}
//守护进程写日志
//./a.out -d 进程守护进程模式
//./a.out 非守护进程模式
int main(int argc, char * const argv[])
{
int ch;
int flag = 0;
while((ch = getopt(argc,argv,"d")) != -1)
{
switch(ch)
{
case 'd':
flag = 1;
break;
}
}
if(flag)
{
deamon_mode();
}
printf("hello word.\n");
while(1);
exit(EXIT_SUCCESS);
}
后台打印log
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <string.h>
void deamon_mode()
{
pid_t pid;
//创建子进程,父进程退出
if((pid = fork()) < 0)
{
perror("Fail fork");
exit(EXIT_FAILURE);
}
if(pid > 0)
{
exit(EXIT_SUCCESS);
}
//创建新会话期
if(setsid() < 0)
{
perror("Fail to setsid");
exit(EXIT_FAILURE);
}
//改变工作目录为"/"
chdir("/");
//重设文件掩码
umask(0);
//关闭不需要的文件描述符
close(0);
close(1);
close(2);
return ;
}
int get_line(FILE *fp)
{
int line = 0;
char buf[1024];
//buf:....\n\0
while(fgets(buf,sizeof(buf),fp) != NULL)
{
if(buf[strlen(buf) - 1] == '\n')
line ++;
}
return line;
}
void do_log(char *name)
{
FILE *fp;
time_t tim;
struct tm *ptm;
int line = 0;
if((fp = fopen(name,"a+")) == NULL)
{
fprintf(stderr,"Fail to fopen %s : %s.\n",name,strerror(errno));
return;
}
line = get_line(fp);
while(1)
{
tim = time(NULL);
ptm = localtime(&tim);
fprintf(fp,"%d,%d-%d-%d %d:%d:%d.\n",++line,ptm->tm_year + 1900,ptm->tm_mon + 1,\
ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec);
fflush(fp);
sleep(1);
}
return ;
}
//练习:守护进程写日志
//./a.out -d 进程守护进程模式
//./a.out 非守护进程模式
//./a.out -d file
//./a.out file
int main(int argc, char * const argv[])
{
int ch;
int flag = 0;
while((ch = getopt(argc,argv,"d")) != -1)
{
switch(ch)
{
case 'd':
flag = 1;
break;
}
}
if(flag)
{
deamon_mode();
}
do_log(argv[optind]);
exit(EXIT_SUCCESS);
}
经验证后台打印日志代码有bug,修复如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
void deamon_mode()
{
pid_t pid;
//创建子进程,父进程退出
if((pid = fork()) < 0)
{
perror("Fail fork");
exit(EXIT_FAILURE);
}
if(pid > 0)
{
exit(EXIT_SUCCESS);
}
//创建新会话期
if(setsid() < 0)
{
perror("Fail to setsid");
exit(EXIT_FAILURE);
}
//改变工作目录为"/"
chdir("/");
//重设文件掩码
umask(0);
//关闭不需要的文件描述符
close(0);
close(1);
close(2);
return ;
}
int get_line(FILE *fp)
{
int line = 0;
char buf[1024];
//buf:....\n\0
while(fgets(buf,sizeof(buf),fp) != NULL)
{
if(buf[strlen(buf) - 1] == '\n')
line ++;
}
return line;
}
void do_log(char *name, FILE *fp)
{
time_t tim;
struct tm *ptm;
int line = 0;
line = get_line(fp);
while(1)
{
tim = time(NULL);
ptm = localtime(&tim);
fprintf(fp,"%d,%d-%d-%d %d:%d:%d.\n",++line,ptm->tm_year + 1900,ptm->tm_mon + 1,\
ptm->tm_mday,ptm->tm_hour,ptm->tm_min,ptm->tm_sec);
fflush(fp);
sleep(1);
}
return ;
}
//练习:守护进程写日志
//./a.out -d 进程守护进程模式
//./a.out 非守护进程模式
//./a.out -d file
//./a.out file
int main(int argc, char * const argv[])
{
int ch;
int flag = 0;
while((ch = getopt(argc,argv,"d")) != -1)
{
switch(ch)
{
case 'd':
flag = 1;
break;
}
}
FILE *fp;
if((fp = fopen(argv[optind],"a+")) == NULL)
{
fprintf(stderr,"Fail to fopen %s : %s.\n",argv[optind],strerror(errno));
return -1;
}
if(flag)
{
deamon_mode();
}
do_log(argv[optind], fp);
exit(EXIT_SUCCESS);
}
部分参考
liumengyang1992 本文链接:https://blog.csdn.net/liumengyang1992/article/details/99430671