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