当我创建一个守护进程时,fopen()似乎不起作用

时间:2016-02-07 23:35:34

标签: c process fopen daemon

这是我的主要源代码:

int main(int argc, char *argv[]) {
    [...]

    if (become_daemon(0) == -1) {
        exit(EXIT_FAILURE);
    }

    while (main_loop == LOOP_CONTINUE) {
        [...]

        if (log_data(date_temp, data_processed) < 0) {
            [...]
        } else {
            [...]
        }
        sleep(measure_rate);
    }
    [...]
}

这里是我的函数定义:

int become_daemon(int flags) {
    int maxfd, fd;

    switch (fork()) {
      case -1:
        return -1;
      case 0:
        break;
      default:
        exit(EXIT_SUCCESS);
    }

    if (setsid() == -1)
        return -1;

    switch (fork()) {
      case -1:
        return -1;
      case 0:
        break;
      default:
        exit(EXIT_SUCCESS);
    }

    if (!(flags & BD_NO_MASK0))
        umask(0);

    if (!(flags & BD_NO_CHDIR))
        chdir("/");

    if (!(flags & BD_NO_CLOSE_FILE)) {
        maxfd = sysconf(_SC_OPEN_MAX);
        if (maxfd == -1)
            maxfd = BD_MAX_CLOSE;

        for (fd = 0; fd < maxfd; fd++)
            close(fd);
    }

    if (!(flags & BD_NO_REOPEN_STD_FDS)) {
        close(STDIN_FILENO);

        fd = open("/dev/null", O_RDWR);

        if (fd != STDIN_FILENO)
            return -1;
        if (dup2(STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO)
            return -1;
        if (dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO)
            return -1;
    }
    return 0;
}

int log_data(char *date, double array_data[DATA_NUM]) {
    FILE *file;

    if ((file = fopen(DATALOG_FILE, "a")) == NULL)
        return -1;

    fprintf(file, "%s ; %.2f ; %.2f ; %.2f ; %.2f ; %.2f ; %.2f\n",
            date, array_data[0], array_data[1], array_data[2],
            array_data[3], array_data[4], array_data[5]);

    fclose(file);

    return 0;
}

这是我的问题:

当我编译我的代码并激活become_daemon()函数然后执行程序时,文件DATALOG_FILE(它是"xxxxxx.txt"的定义)它没有被创建。如果我在没有become_daemon()函数调用的情况下编译,程序运行正常,文件就会被创建。

我甚至注意到,如果我添加行

sudo /my/folder/program

rc.local中在启动时运行它,它会像我想的那样启动,但即使在这种情况下,它也不会创建文件DATALOG_FILE。

我是守护进程的新手,所以有人能告诉我这种行为的原因吗?

1 个答案:

答案 0 :(得分:3)

正如Ctx在其评论中提到的,函数become_daemon可能会将当前目录更改为/。如果DATALOG_FILE是相对文件名,例如"xxxxxx.txt",那么守护程序将无法在系统根目录中创建它,除非它具有root权限。

要么通过将BD_NO_CHDIR作为参数传递给become_daemon来改变当前目录,要么使DATALOG_FILE成为绝对路径。