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 std::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)