//守护进程--读文件
#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=0;
int fd2=0;
char buf[100]={0};
//打开管道文件(管道文件一般用系统函数读取)
int fd=open("/home/test/1/fifo1",O_RDONLY);
if(fd==-1)
{
writelog("/home/test/1/mylog.txt","open the fifio1 failed !");
//printf("open the fifio1 failed ! error message :%s
",strerror(errno));
return;
}
len=read(fd,buf,sizeof(buf));
if(len<=0)
{
writelog("/home/test/1/mylog.txt","read the fifo1 is failed !");
//printf("read the fifo1 is failed ! error code is %d
",len);
return;
}
if(buf[strlen(buf)-1]=='
')
{
buf[strlen(buf)-1]=0;
}
writelog("/home/test/1/mylog.txt",buf);
//close the fifo1
close(fd);
//关闭标准输出
close(STDOUT_FILENO);
//将指定文件作为标准输出--输出文件只能写
fd2=open(buf,O_WRONLY);
memset(buf,0,sizeof(buf));
sprintf(buf,"fd2=%d
",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 !
");
return -1;
}
//管道文件不使用C语言库函数
char buf[100]={0};
int fd=open(path,O_RDONLY);
if(fd==-1)
{
printf("open the fifo failed ! error message :%s
",strerror(errno));
return -1;
}
/*
read()函数在读取管道文件的时候,会阻塞进程,当管道的另一端正常关闭,read函数返回0,非正常关闭返回-1
*/
while(read(fd,buf,sizeof(buf))>0)
{
printf("%s",buf);
memset(buf,0,sizeof(buf));
}
close(fd);
return 0;
}
//创建守护进程
int setdaemon()
{
pid_t pid=fork();
if(pid==-1)
{
printf("fork error ! error message :%s
",strerror(errno));
exit(0);
}
if(pid==0)
{
//child process
setsid();
chdir("/");
umask(0);
/*
close(STDIN_FILENO);
close(STDERR_FILENO);
*/
}
if(pid>0)
{
exit(0);
}
return 0;
}
//捕捉消息
int mysignnal(int sign,void (*func)(int))
{
struct sigaction act,oact;
act.sa_handler=func;
sigemptyset(&act.sa_mask);
act.sa_flags=0;
return sigaction(sign,&act,&oact);
}
int main(int arg,char * args[])
{
if(arg<2)
{
printf("请输入一个参数!
");
return -1;
}
setdaemon();
//注册消息
mysignnal(SIGINT,catch_signal);
//readmyfile(args[1]);
while(1)
{
printf("I'm living!
");
sleep(1);
}
return 0;
}
.SUFFIXES:.c .o
CC=gcc
SRCS=tec01.c
OBJS=$(SRCS:.c=.o)
EXEC=tecd
start:$(OBJS)
$(CC) -L. -lmylog -o $(EXEC) $(OBJS)
@echo "------OK----------"
.c.o:
$(CC) -Wall -g -o $@ -c $<
clean:
rm -f $(OBJS)
rm -f $(EXEC)

小结:
这个程序写代码20分钟完成,但是调试却花了40分钟,我给守护进程发送信号,守护进程并不输出内容,其中我犯了两个错误
--第一个错误;我在创建守护进程的时候,将标准输出,标准输入,标准出错这三个文件描述符全部关闭了,导致我在listenfifo中打开的文件描述符实际上是标准输入(即fd=0)
我通过日志观察到fd=0,使我想到我的文件描述符可能全部被关闭了,另外这个程序中我自己操作打开了2个文件描述符,一个是管道文件的,一个屏幕输出文件的
--第二个错误
标准输出应该是一个只写文件,但是我在open()函数中用的是O_RDONLY,所以也没有结果。