首页 > 代码库 > linux守护进程

linux守护进程

#include <iostream>
#include <unistd.h>
//#include "curl/curl.h"
#include "app_curl.h"
#include "youtube_package.h"
#include "CAutoMail.h"
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <sys/resource.h>

#define LOCKFILE "./daemon.pid"
#define LOCKMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)

int lockfile(int fd);


int lockfile(int fd)
{
    struct flock fl;

    fl.l_len=0;
    fl.l_type=F_WRLCK;
    fl.l_whence=SEEK_SET;
    fl.l_start=0;

    return (fcntl(fd,F_SETLK,&fl));
}
int already_running(void)
{
    int fd;
    char buf[16]={0};
    int nResult=0;
    if(0>(fd=open(LOCKFILE,O_RDWR|O_CREAT,LOCKMODE)))
    {
        COMM_LOG("youtube",LOG_ERROR,"can‘t open %s:%s",LOCKFILE,strerror(errno));
        exit(1);
    }
    if(lockfile(fd)<0)
    {
        if(errno==EACCES || errno==EAGAIN)
        {
            close(fd);
            return 1;
        }
        COMM_LOG("youtube",LOG_ERROR,"can‘t lock %s:%s",LOCKFILE,strerror(errno));
        exit(1);
    }
    nResult=ftruncate(fd,0);
    snprintf(buf,sizeof(buf),"%ld",(long)getpid());
    nResult=write(fd,buf,strlen(buf)+1);
    
    return 0;
}

void daemonize(const char *cmd)
{
    int i,fd0,fd1,fd2;
    pid_t pid;
    struct rlimit rl;
    struct sigaction sa;

    //umask(0);

    if((pid=fork())<0)
    {
        COMM_LOG("youtube",LOG_ERROR,"%s","pid can‘t fork");
        exit(0);
    }else if(pid!=0)
    {
        exit(0);
    }
    setsid();

    sa.sa_handler=SIG_IGN;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags=0;
    if(sigaction(SIGHUP,&sa,NULL)<0)
    {
        COMM_LOG("youtube",LOG_ERROR,"%s","can‘t ignore SIGHUP");
        exit(0);        
    }
    if((pid=fork())<0)
    {
        COMM_LOG("youtube",LOG_ERROR,"%s","pid can‘t fork");
        exit(0);
    }else if(pid!=0)
    {
        exit(0);
    }  
    //if(chdir("/")<0)
    //{
    //    COMM_LOG("youtube",LOG_ERROR,"%s","can‘t change directory to /");
    //    exit(0);        
    //}
    if(rl.rlim_max==RLIM_INFINITY)
        rl.rlim_max=1024;
    for(i=0;i<rl.rlim_max;i++)
        close(i);

    fd0=open("/dev/null",O_RDWR);
    fd1=dup(0);
    fd2=dup(0);
    if(fd0!=0 || fd1!=1 || fd2!=2)
    {
        COMM_LOG("youtube",LOG_ERROR,"%s,%d,%d,%d","unexpected file descriprors",fd0,fd1,fd2);
        exit(1);           
    }


}

int main()
{
    int ret=0;
#if 0
    daemonize(NULL);
    if(already_running())
    {

        COMM_LOG("youtube",LOG_ERROR,"%s","daemon already running");
        exit(1);
    }
#endif
    //CurlDownLoad("46.51.223.70/script/youtube_rev.ver","youtube_rev.ver",CurlWriteToFile);
    // printf("hello world\n");
    YtbDecrypt::GetInstance();//解密前置
    //CAutoMail::GetInstance()->SendMail("test","this is a test file!");
    //CAutoMail::GetInstance()->SendMail("test","你好啊,中文测试!");
    //printf("jiexi0--\n");    
    while(1)
    {
        sleep(10);
    }
    return ret;
}

 

关系所有的文件描述符:

for(i=getdtablesize()-1;i>=0;--i)

  close(i);

NAME
       getdtablesize - get descriptor table size

SYNOPSIS
       #include <unistd.h>

       int getdtablesize(void);

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       getdtablesize():
           Since glibc 2.12:
               _BSD_SOURCE ||
                   !(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)
           Before glibc 2.12:
               _BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED

DESCRIPTION
       getdtablesize()  returns  the maximum number of files a process can have open, one more than the largest possible value for a file
       descriptor.

RETURN VALUE
       The current limit on the number of open files per process.

ERRORS
       On Linux, getdtablesize() can return any of the errors described for getrlimit(2); see NOTES below.

对服务器编程以改变它的控制TTY:

使进程与其控制终端分开:

fd=open("/dev/tty",0_RDWR);

(void)ioctl(fd,TIOCNOTTY,0);

(void)close(fd);

 

每个进程继承了一个进程组的成员关系,为避免接收其父进程有意义的下信号,服务器必须离开其父进程的进程组。

对服务器编程以设置其进程组:

(void)setpgrp(0,getpid());