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

fopen() seems not work when I create a daemon process

这是我的主要源代码:

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.

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

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

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