import posix import os except sleep ## Daemonize var pidFileInner: string fi, fo, fe: File proc onStop(sig: cint) {.noconv.} = close(fi) close(fo) close(fe) removeFile(pidFileInner) quit(QuitSuccess) proc daemonize*(pidfile, si, so, se: string, daemonMain: proc(): void): Pid = if fileExists(pidfile): raise newException(IOError, "pidfile " & pidfile & " already exists, daemon already running?") let pid1 = fork() # Are we the child process? if pid1 == 0: # Yes, so let's get ready to execute the main code given to us. discard chdir("/") discard setsid() discard umask(0) # Fork again... but I'm not sure why. let pid2 = fork() # We don't need the intermediate process, so if we are not the child this # time, lets just quit if pid2 > 0: quit(QuitSuccess) # If we are the grandchild let's set up our environment. flushFile(stdout) flushFile(stderr) if si.len > 0: fi = open(si, fmRead) discard dup2(getFileHandle(fi), getFileHandle(stdin)) if so.len > 0: fo = open(so, fmAppend) discard dup2(getFileHandle(fo), getFileHandle(stdout)) if se.len > 0: fe = open(se, fmAppend) discard dup2(getFileHandle(fe), getFileHandle(stderr)) pidFileInner = pidfile # Add hooks to cleanup after ourselves when we're asked to die. signal(SIGINT, onStop) signal(SIGTERM, onStop) # Find out what our actual PID is and save it let childPid = getpid() writeFile(pidfile, $childPid) # Finally, execute our main daemonMain() return pid1