//守护进程--读文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include "mylog.h"
//监听管道
void listenfifo()
{
//file size
int len=;
int fd2=;
char buf[]={};
//打开管道文件(管道文件一般用系统函数读取)
int fd=open("/home/test/1/fifo1",O_RDONLY);
if(fd==-)
{
writelog("/home/test/1/mylog.txt","open the fifio1 failed !");
//printf("open the fifio1 failed ! error message :%s\n",strerror(errno));
return;
}
len=read(fd,buf,sizeof(buf));
if(len<=)
{
writelog("/home/test/1/mylog.txt","read the fifo1 is failed !");
//printf("read the fifo1 is failed ! error code is %d\n",len);
return;
}
if(buf[strlen(buf)-]=='\n')
{
buf[strlen(buf)-]=;
}
writelog("/home/test/1/mylog.txt",buf);
//close the fifo1
close(fd);
//关闭标准输出
close(STDOUT_FILENO);
//将指定文件作为标准输出--输出文件只能写
fd2=open(buf,O_WRONLY);
memset(buf,,sizeof(buf));
sprintf(buf,"fd2=%d\n",fd);
writelog("/home/test/1/mylog.txt",buf);
}
//消息处理机制
void catch_signal(int sign)
{
switch(sign)
{
case SIGINT:
listenfifo();
break;
}
}
//读文件
int readmyfile(const char * path)
{
if(path==NULL)
{
printf("param is not allow NULL !\n");
return -;
}
//管道文件不使用C语言库函数
char buf[]={};
int fd=open(path,O_RDONLY);
if(fd==-)
{
printf("open the fifo failed ! error message :%s\n",strerror(errno));
return -;
}
/*
read()函数在读取管道文件的时候,会阻塞进程,当管道的另一端正常关闭,read函数返回0,非正常关闭返回-1
*/
while(read(fd,buf,sizeof(buf))>)
{
printf("%s",buf);
memset(buf,,sizeof(buf));
}
close(fd);
return ;
}
//创建守护进程
int setdaemon()
{
pid_t pid=fork();
if(pid==-)
{
printf("fork error ! error message :%s\n",strerror(errno));
exit();
}
if(pid==)
{
//child process
setsid();
chdir("/");
umask();
/*
close(STDIN_FILENO);
close(STDERR_FILENO);
*/
}
if(pid>)
{
exit();
}
return ;
}
//捕捉消息
int mysignnal(int sign,void (*func)(int))
{
struct sigaction act,oact;
act.sa_handler=func;
sigemptyset(&act.sa_mask);
act.sa_flags=;
return sigaction(sign,&act,&oact);
}
int main(int arg,char * args[])
{
if(arg<)
{
printf("请输入一个参数!\n");
return -;
}
setdaemon();
//注册消息
mysignnal(SIGINT,catch_signal);
//readmyfile(args[1]);
while()
{
printf("I'm living!\n");
sleep();
}
return ;
}
小结:
这个程序写代码20分钟完成,但是调试却花了40分钟,我给守护进程发送信号,守护进程并不输出内容,其中我犯了两个错误
--第一个错误;我在创建守护进程的时候,将标准输出,标准输入,标准出错这三个文件描述符全部关闭了,导致我在listenfifo中打开的文件描述符实际上是标准输入(即fd=0)
我通过日志观察到fd=0,使我想到我的文件描述符可能全部被关闭了,另外这个程序中我自己操作打开了2个文件描述符,一个是管道文件的,一个屏幕输出文件的
--第二个错误
标准输出应该是一个只写文件,但是我在open()函数中用的是O_RDONLY,所以也没有结果。