Hi all,

I tried to write a Linux daemon in D 2.065 (by translating one in C we use at work). My basic skeleton works well. But as soon as I start allocating memory it crashed with several 'core.exception.InvalidMemoryOperationError's.

My questions:
1. Are there any special considerations w.r.t. the GC after using fork()? Or must it be disabled? 2. Is it allowed to use stdlib's exit() without cleaning up after the runtime (as a normal end of program probably does)? Or is there a safe D exit()?

I could not find any working daemon examples, so any help is appreciated!

Bye,
Jeroen

---

My code so far:

module testdaemon;

import std.stdio;
import std.c.stdlib : exit, EXIT_FAILURE, EXIT_SUCCESS;
import core.thread : Thread, dur;
import core.sys.posix.sys.stat : umask;
import core.sys.posix.unistd : fork, setsid, chdir, close, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO;

void daemonize()
{
        // fork this process
        auto pid = fork();
        if (pid == -1) exit(EXIT_FAILURE);

        // this is the parent; terminate it
        if (pid > 0)
        {
                writefln("Starting daemon mode, process id = %d\n", pid);
                // is this ok, or should we clean up after the runtime?
                exit(EXIT_SUCCESS);
        }
        
        //unmask the file mode
        umask(0);
        
        // become process group leader
        auto sid = setsid();
        if(sid < 0) exit(EXIT_FAILURE);
        
        // do not lock any directories
        chdir("/");

        // Close stdin, stdout and stderr
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);
}

void main()
{       
        auto log = File("testdaemon.log", "w");
        daemonize();
        while(true)
        {       
                try
                {       
// this statement causes core.exception.InvalidMemoryOperationError
                        // auto t = new char[4096];

                        log.write(".");
                }
                catch(Exception e)
                {
                        log.write(e.msg);
                }
                finally
                {
                        log.flush();
                }
                Thread.sleep(dur!("seconds")(5));
        }
}

Reply via email to