0

I am following a quick guide how to create daemon process in C, that was created as an answer to one of Stack Overflow questions.

And here is a problem, to make this code easier for me I have created a file, where I am logging some debug data, but when I make a second fork(), my new child seems not to log anything. I check the list of processes that exists. I have no idea why it did not print anything to my file. Any ideas? 0.o

My adjusted code:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <syslog.h>

#define LOG_FILE "/local_pv/asiwek/daemon_test/daemon_log.log"

static void skeleton_daemon(FILE* file)
{
    pid_t pid;

    /* Fork off the parent process */
    pid = fork();

    /* An error occurred */
    if (pid < 0)
        exit(EXIT_FAILURE);

    /* Success: Let the parent terminate */
    if (pid > 0)
        exit(EXIT_SUCCESS);
    
    fprintf(file ,"I'm a child! \n");
    /* On success: The child process becomes session leader */
    if (setsid() < 0)
    {
        fprintf(file ,"ERROR: setsid()! \n");
        exit(EXIT_FAILURE);
    }

    /* Catch, ignore and handle signals */
    //TODO: Implement a working signal handler */
    signal(SIGCHLD, SIG_IGN);
    signal(SIGHUP, SIG_IGN);

    /* Fork off for the second time*/
    pid = fork();
    
    /* An error occurred */
    if (pid < 0)
    {   
        fprintf(file ,"ERROR: fork()! \n");
        exit(EXIT_FAILURE);
    }
    /* Success: Let the parent terminate */
    if (pid > 0)
    {
        fprintf(file, "I'm a parent of the child! pid : %d", pid);
        exit(EXIT_SUCCESS);
    }
    
    fprintf(file ,"New Child!! \n"); // here program stops logging
    
    /* Set new file permissions */
    umask(0);

    /* Change the working directory to the root directory */
    /* or another appropriated directory */
    chdir("/local_pv/asiwek/daemon_test/");
    fprintf(file ,"chdir \n");

    /* Close all open file descriptors */
    int x;
    for (x = sysconf(_SC_OPEN_MAX); x>=0; x--)
    {
        close (x);
    }

    /* Open the log file */
    //openlog ("firstdaemon", LOG_PID, LOG_DAEMON);
    fprintf(file ,"skeleton_daemon() end. \n");
}

int main()
{
    FILE* f = fopen(LOG_FILE, "w");
    skeleton_daemon(f);
    fprintf(f ,"Oh boy I am a daemon!!! \n");

    while (1)
    {
        //TODO: Insert daemon code here.
      //  syslog (LOG_NOTICE, "First daemon started.");
        fprintf(f, "Some log.");
        sleep (200);
        break;
    }

    //syslog (LOG_NOTICE, "First daemon terminated.");
    //closelog();
    fclose(f);

    return EXIT_SUCCESS;
}
Rachid K.
  • 2,562
  • 2
  • 3
  • 17
Aleksander
  • 53
  • 6
  • With systems there should be no reason to fork to create a daemon. Check systems docks. – doron Sep 14 '20 at 11:45
  • Can you elaborate, @doron? You have lost me. – John Bollinger Sep 14 '20 at 11:50
  • 1
    Don't you suppose that the code meant to "`/* Close all open file descriptors */`" would present a problem for your previously-opened log file if it is successful in its appointed task? – John Bollinger Sep 14 '20 at 11:55
  • That could be true, but when I comment this loop the problem still occours. And my program stops logging before closing file descriptors, as I mentioned in my question. – Aleksander Sep 14 '20 at 12:00
  • 1
    Your program seems to have a buffering issue. When I add `setvbuf(f, NULL, _IONBF, 0);` before `skeleton_daemon(f);` I get the output "New Child!!". (There is a missing newline in `fprintf(file, "I'm a parent of the child! pid : %d", pid);`.) See also https://stackoverflow.com/q/2530663/10622916 – Bodo Sep 14 '20 at 12:10
  • 1
    @John sorry, I meant to say systemd. so check the systemd documentation on how to write a systemd service – doron Sep 14 '20 at 12:12
  • @Bodo Thanks it worked now! :D – Aleksander Sep 14 '20 at 12:14

0 Answers0