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