Reply to comment

Making a Linux Daemon

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:

Advanced Programming in the UNIX(R) Environment (2nd Edition) (Addison-Wesley Professional Computing Series)

And paperback is now available too:

Advanced Programming in the UNIX Environment: Paperback Edition (2nd Edition) (Addison-Wesley Professional Computing Series)

Reply

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <blockquote>
  • Lines and paragraphs break automatically.
  • You may post PHP code. You should include <?php ?> tags.
  • Web page addresses and e-mail addresses turn into links automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>, <cpp>. The supported tag styles are: <foo>, [foo]. PHP source code can also be enclosed in <?php ... ?> or <% ... %>.
  • Images can be added to this post.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
11 + 7 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.