I just faced this problem at work and found a great little document that gave me the insight I needed. I'm posting it here for anyone else who is interested.
http://www.linuxprofilm.com/articles/linux-daemon-howto.html
Update
This page is currently the most popular on the site and it was well overdue for a refresh.
As stated in comments below the simplest way to do this in Linux is to use the daemon() system call. However, this function does not exist in System V based Unix distributions (ie, Solaris).
The basic concept that needs to happen is that your application forks itself and shuts down its standard input/output/error connections.
The C++ code I use for this is:
//! daemonize the currently running programming //! Note: the calls to strerror are not thread safe, but that should not matter //! as the application is only just starting up when this function is called //! \param[in] dir which dir to ch to after becoming a daemon //! \param[in] stdinfile file to redirect stdin to //! \param[in] stdoutfile file to redirect stdout from //! \param[in] stderrfile file to redirect stderr to void System::daemonize(const string &dir = "/", const std::string &stdinfile = "/dev/null", const std::string &stdoutfile = "/dev/null", const std::string &stderrfile = "/dev/null") { umask(0); rlimit rl; if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { //can't get file limit throw std::runtime_error(strerror(errno)); } pid_t pid; if ((pid = fork()) < 0) { //Cannot fork! throw std::runtime_error(strerror(errno)); } else if (pid != 0) { //parent exit(0); } setsid(); if (!dir.empty() && chdir(dir.c_str()) < 0) { // Oops we couldn't chdir to the new directory throw std::runtime_error(strerror(errno)); } if (rl.rlim_max == RLIM_INFINITY) { rl.rlim_max = 1024; } // Close all open file descriptors for (unsigned int i = 0; i < rl.rlim_max; i++) { close(i); } int fd0 = open(stdinfile.c_str(), O_RDONLY); int fd1 = open(stdoutfile.c_str(), O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR); int fd2 = open(stderrfile.c_str(), O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR); if (fd0 != STDIN_FILENO || fd1 != STDOUT_FILENO || fd2 != STDERR_FILENO) { //Unexpected file descriptors throw runtime_error("new standard file descriptors were not opened as expected"); } }
By removing the references to std::string and throw this code is easily converted to C code.
The book "Advanced Programming in the UNIX Environment" covers in depth how to deamonize a process, why you would want to and what happens under the hood. I keep it as a desk reference and highly recommend it.
The hardback version:
And paperback is now available too:
Comments
A bit complex
Using the daemon() system call would eliminate 3/4 of the program.
If it exists...
The daemon() system call would have been a good choice at the time that I posted that comment, good point. However, it is a nonstandard call and may or may not exist on the platform you are writing for.
Linux Daemon how-to document gone!
Ah well.. looks like that how-to write a Daemon article is toast. Anybody have a copy of their own - there was a PDF originally as well. Looking to create some Daemons using C on embedded Linux.
Thanks muchly.
http://www.linuxprofilm.com/a
http://www.linuxprofilm.com/articles/linux-daemon-howto.html
http://web.archive.org/web/20
http://web.archive.org/web/20060603181849/http://www.linuxprofilm.com/ar...
Thank you
Linux Rules!
Thank you.
how to restart a daemon after it terminates in source code
I am trying to find a way to restart (respawn) the daemon after it dies, is there a way to do this in the daemon source code?
Thanks
Mike
Respawning a killed Daemon
Well. I am not aware of a way of doing this in the Daemon's source code itself. I don't think it is even possible because if you application is dead, there is nothing much it can do to revive itself. :-) What can be done instead is to have an entry for your Daemon in /etc/inittab specifying the "respawn" option. This way, init will take care of respawning your Daemon if it is killed.
Re: Respawning a killed Daemon
As a partial solution, you can install signal handlers in your daemon to respond to some signals. (SIGTERM maybe). But there is nothing much you can do about SIGKILL. So, /etc/inittab is a complete solution.
References to function parameters
I do not understand the need to reference all the parameters in the function header, is it on intent, or just some sort of concrete and special needs of your particular implementation? Thx. Juraj
Passing by const reference
I assume you are referring to the function header in the code, referenced above. As this code is intended for C++ usage (but can easily be converted to C) I used the very common "const reference" in C++, which is a normal optimization technique.
By using the const reference we are getting the performance of passing by reference (as opposed to passing by copy) combined with the guarantee (const) that the user of the function may not modify the parameters.
This technique is not considered to be "premature optimization," it falls more into the category of "best practices."