标签:
//守护进程--读文件 #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\n",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\n",len); return; } if(buf[strlen(buf)-1]==‘\n‘) { 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\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 -1; } //管道文件不使用C语言库函数 char buf[100]={0}; int fd=open(path,O_RDONLY); if(fd==-1) { printf("open the fifo failed ! error message :%s\n",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\n",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("请输入一个参数!\n"); return -1; } setdaemon(); //注册消息 mysignnal(SIGINT,catch_signal); //readmyfile(args[1]); while(1) { printf("I‘m living!\n"); 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,所以也没有结果。
标签:
原文地址:http://www.cnblogs.com/zhanggaofeng/p/5859805.html