I can already say that it nevertheless works with DMD git. Will test soon with Digger, unfortunately Bitbucket is currently down, and Digger depends on it.

In the meantime I installed DMD 2.066 and I changed the exit() function after the fork as Dicebot suggested. Unfortunately I got the same result:

$ ./testdaemon
Starting daemon mode, process id = 30510

core.exception.InvalidMemoryOperationError@(0)
core.exception.InvalidMemoryOperationError@(0)

I think the issue is the way the parent is stopped after the fork(). Being quite new to D I have to familiarise myself some more with D's runtime and GC to see it...

---

The changed example code:

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;

extern (C)
{
        void _Exit(int);
}

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);
                _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