posix_daemon.cpp 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. //
  2. // $Id$
  3. //
  4. #include<__vic/posix/process.h>
  5. #include<__vic/throw_errno.h>
  6. #include<sys/fcntl.h>
  7. #include<unistd.h>
  8. #include<stdlib.h> // BSD
  9. namespace __vic { namespace posix {
  10. //----------------------------------------------------------------------------
  11. void daemon(bool nochdir, bool noclose)
  12. {
  13. #if defined(__linux__) || \
  14. defined(__FreeBSD__) || \
  15. defined(__QNX__)
  16. // Redirect to the system call
  17. if(::daemon(nochdir, noclose)) throw_errno("daemon");
  18. #else
  19. // Use own implementation
  20. switch(fork())
  21. {
  22. case -1: throw_errno("fork");
  23. case 0: break;
  24. default: _exit(0); // parent exit
  25. }
  26. setsid();
  27. if(!nochdir) chdir("/");
  28. if(!noclose)
  29. {
  30. int fd = open("/dev/null", O_RDWR | O_NOCTTY);
  31. struct fd_closer : private non_copyable
  32. {
  33. int fd;
  34. explicit fd_closer(int fd) : fd(fd) {}
  35. ~fd_closer() { if(fd > 2) close(fd); }
  36. } closer(fd);
  37. if(fd == -1
  38. || dup2(fd, 0) == -1
  39. || dup2(fd, 1) == -1
  40. || dup2(fd, 2) == -1
  41. ) throw_errno("daemon: redirection to /dev/null failed");
  42. }
  43. #endif
  44. }
  45. //----------------------------------------------------------------------------
  46. }} // namespace