sys.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /** @file sys.c
  2. * @brief System-related faux functions.
  3. */
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <assert.h>
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10. #include <fcntl.h>
  11. #include <unistd.h>
  12. #include "faux/faux.h"
  13. /** Implementation of daemon() function.
  14. *
  15. * The original daemon() function is not POSIX. Additionally parent doesn't
  16. * create PID file as UNIX services do. So after parent exiting there is no
  17. * PID file yet. This function fix that problems.
  18. *
  19. * @param [in] nochdir On zero changes working dir to "/". Compatible with daemon().
  20. * @param [in] noclose On zero redirects standard streams to "/dev/null". Compatible with daemon().
  21. * @param [in] pidfile Name of PID file to create.
  22. * @param [in] mode PID file mode.
  23. * @return BOOL_TRUE on success, BOOL_FALSE else.
  24. * @sa daemon()
  25. */
  26. bool_t faux_daemon(int nochdir, int noclose, const char *pidfile, mode_t mode)
  27. {
  28. pid_t pid = -1;
  29. pid = fork();
  30. if (-1 == pid)
  31. return BOOL_FALSE;
  32. // Parent
  33. if (pid > 0) {
  34. // Parent writes PID file
  35. if (pidfile && (pidfile[0] != '\0')) {
  36. int fd = -1;
  37. if ((fd = open(pidfile,
  38. O_WRONLY | O_CREAT | O_EXCL | O_TRUNC,
  39. mode)) >= 0) {
  40. ssize_t r = 0;
  41. char str[20] = {};
  42. snprintf(str, sizeof(str), "%u\n", pid);
  43. str[sizeof(str) - 1] = '\0';
  44. r = write(fd, str, strlen(str));
  45. r = r; // Happy compiler
  46. close(fd);
  47. }
  48. }
  49. _exit(0); // Exit parent
  50. }
  51. // Child
  52. if (setsid() == -1)
  53. return BOOL_FALSE;
  54. if (0 == nochdir) {
  55. if (chdir("/"))
  56. return BOOL_FALSE;
  57. }
  58. if (0 == noclose) {
  59. int fd = -1;
  60. fd = open("/dev/null", O_RDWR, 0);
  61. if (fd < 0)
  62. return BOOL_FALSE;
  63. dup2(fd, STDIN_FILENO);
  64. dup2(fd, STDOUT_FILENO);
  65. dup2(fd, STDERR_FILENO);
  66. if (fd > STDERR_FILENO)
  67. close(fd);
  68. }
  69. return BOOL_TRUE;
  70. }