daemonise.c 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /*
  2. * daemonise.c:
  3. * Fairly generic "Turn the current process into a daemon" code.
  4. *
  5. * Copyright (c) 2016-2017 Gordon Henderson.
  6. *********************************************************************************
  7. */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <unistd.h>
  11. #include <syslog.h>
  12. #include <signal.h>
  13. #include <sys/stat.h>
  14. #include "daemonise.h"
  15. void daemonise (const char *pidFile)
  16. {
  17. pid_t pid ;
  18. int i ;
  19. FILE *fd ;
  20. syslog (LOG_DAEMON | LOG_INFO, "Becoming daemon") ;
  21. // Fork from the parent
  22. if ((pid = fork ()) < 0)
  23. {
  24. syslog (LOG_DAEMON | LOG_ALERT, "Fork no. 1 failed: %m") ;
  25. exit (EXIT_FAILURE) ;
  26. }
  27. if (pid > 0) // Parent - terminate
  28. exit (EXIT_SUCCESS) ;
  29. // Now running on the child - become session leader
  30. if (setsid() < 0)
  31. {
  32. syslog (LOG_DAEMON | LOG_ALERT, "setsid failed: %m") ;
  33. exit (EXIT_FAILURE) ;
  34. }
  35. // Ignore a few signals
  36. signal (SIGCHLD, SIG_IGN) ;
  37. signal (SIGHUP, SIG_IGN) ;
  38. // Fork again
  39. if ((pid = fork ()) < 0)
  40. {
  41. syslog (LOG_DAEMON | LOG_ALERT, "Fork no. 2 failed: %m") ;
  42. exit (EXIT_FAILURE) ;
  43. }
  44. if (pid > 0) // parent - terminate
  45. exit (EXIT_SUCCESS) ;
  46. // Tidying up - reset umask, change to / and close all files
  47. umask (0) ;
  48. chdir ("/") ;
  49. for (i = 0 ; i < sysconf (_SC_OPEN_MAX) ; ++i)
  50. close (i) ;
  51. // Write PID into /var/run
  52. if (pidFile != NULL)
  53. {
  54. if ((fd = fopen (pidFile, "w")) == NULL)
  55. {
  56. syslog (LOG_DAEMON | LOG_ALERT, "Unable to write PID file: %m") ;
  57. exit (EXIT_FAILURE) ;
  58. }
  59. fprintf (fd, "%d\n", getpid ()) ;
  60. fclose (fd) ;
  61. }
  62. }