You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

83 lines
1.6 KiB

  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. {
  29. exit (EXIT_SUCCESS);
  30. }
  31. // Now running on the child - become session leader
  32. if (setsid() < 0)
  33. {
  34. syslog (LOG_DAEMON | LOG_ALERT, "setsid failed: %m");
  35. exit (EXIT_FAILURE);
  36. }
  37. // Ignore a few signals
  38. signal (SIGCHLD, SIG_IGN);
  39. signal (SIGHUP, SIG_IGN);
  40. // Fork again
  41. if ((pid = fork()) < 0)
  42. {
  43. syslog (LOG_DAEMON | LOG_ALERT, "Fork no. 2 failed: %m");
  44. exit (EXIT_FAILURE);
  45. }
  46. if (pid > 0) // parent - terminate
  47. {
  48. exit (EXIT_SUCCESS);
  49. }
  50. // Tidying up - reset umask, change to / and close all files
  51. umask (0);
  52. chdir ("/");
  53. for (i = 0; i < sysconf (_SC_OPEN_MAX); ++i)
  54. {
  55. close (i);
  56. }
  57. // Write PID into /var/run
  58. if (pidFile != NULL)
  59. {
  60. if ((fd = fopen (pidFile, "w")) == NULL)
  61. {
  62. syslog (LOG_DAEMON | LOG_ALERT, "Unable to write PID file: %m");
  63. exit (EXIT_FAILURE);
  64. }
  65. fprintf (fd, "%d\n", getpid());
  66. fclose (fd);
  67. }
  68. }