守护进程--用记录锁实现单个程序以避免多个相同程序

750阅读 0评论2016-09-08 文峰聊书斋
分类:LINUX

#include
#include "daemon.h"

extern void debug_wait (int debug);

void test_to_locked ()
{
    int fd;
    struct flock lock;
    char *buf = "abdcefghijklmnopqrstuvwxyz";
    //begin to test file lock   
    fd = open ("/tmp/mylock.lock", O_RDWR | O_CREAT, 0777);
    if (fd < 0) {
        perror ("Open file error");
        exit (1);
    }

    write (fd, buf, strlen (buf));
    fsync (fd);

    //file be locked?
    lock.l_whence = SEEK_SET;
    lock.l_start = 0;
    lock.l_len = 10;
    lock.l_type = F_WRLCK;
    lock.l_pid = -1;
    if (fcntl (fd, F_GETLK, &lock) < 0) {
        perror ("fcntl failed!");
        exit (1);
    }
//由于记录锁是在内核中,就算程序突然掉点或者突然死掉来不及删除lock文件也会因为程序的死掉而被内核清楚。防止因单纯创建一个LOCK文件带来有可能因没有删除LOCK文件而导致程序再也无法运行的问题。

//  if(lock.l_type == F_WRLCK)
    if (lock.l_type != F_UNLCK) {
        printf ("have a daemon. so quit!\n");
        exit (1);
    }
    //locked file
    lock.l_type = F_WRLCK;
    if (fcntl (fd, F_SETLKW, &lock) < 0) {
        printf ("Lock file failed: type = %d\n", lock.l_type);
        exit (1);
    }
    printf ("file have locked!\n");
}

int daemon_init (void)
{
    pid_t pid;
    int fd0, fd1, fd2, max_fd, i;
    struct rlimit rl;
    struct sigaction sa;


    umask (0);
    signal (SIGHUP, SIG_IGN); //忽略SIGHUP信号
    
    //test_to_locked();
    if ((pid = fork ()) < 0) {
        perror ("fork faild!");
        exit (1);
    } else if (pid != 0) {
        exit (0);
    }

    if (setsid () < 0)
        exit (1);



    if ((pid = fork ()) < 0) {
        perror ("fork faild!");
        exit (1);
    } else if (pid != 0) {
        exit (0);
    }

    chdir ("/");
    //umask(0);
    setpgrp ();
#if 0
    // Get maximum number of file descriptors.
    if (getrlimit (RLIMIT_NOFILE, &rl) < 0) {
        perror ("can't get file limit");
    }
    // Close all open file descriptors.
    if (rl.rlim_max == RLIM_INFINITY)
        rl.rlim_max = 1024;
    for (i = 0; i < rl.rlim_max; i++)
        close (i);
#else
    max_fd = sysconf (_SC_OPEN_MAX);
    for (i = max_fd; i >= 0; i--)
        close (i);
#endif

    //attach file descriptors 0, 1, and 2 to /dev/null.
    fd0 = open ("/dev/null", O_RDWR);
    fd1 = dup (0);
    fd2 = dup (0);

    test_to_locked ();
    //Initialize the log file.
    openlog ("daemon_test", LOG_CONS | LOG_PID, LOG_DAEMON);
    if (fd0 != 0 || fd1 != 1 || fd2 != 2) {
        syslog (LOG_ERR, "unexpected file descriptors %d %d %d", fd0, fd1, fd2);
        exit (1);
    }

    return 0;
}

上一篇:系统日志
下一篇:uboot命令相关结构体