Linux 守护进程二(激活守护进程)

//守护进程--读文件
#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,所以也没有结果。
原文地址:https://www.cnblogs.com/zhanggaofeng/p/5859805.html