sys.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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. char str[20] = {};
  41. snprintf(str, sizeof(str), "%u\n", pid);
  42. str[sizeof(str) - 1] = '\0';
  43. write(fd, str, strlen(str));
  44. close(fd);
  45. }
  46. }
  47. _exit(0); // Exit parent
  48. }
  49. // Child
  50. if (setsid() == -1)
  51. return BOOL_FALSE;
  52. if (0 == nochdir) {
  53. if (chdir("/"))
  54. return BOOL_FALSE;
  55. }
  56. if (0 == noclose) {
  57. int fd = -1;
  58. fd = open("/dev/null", O_RDWR, 0);
  59. if (fd < 0)
  60. return BOOL_FALSE;
  61. dup2(fd, STDIN_FILENO);
  62. dup2(fd, STDOUT_FILENO);
  63. dup2(fd, STDERR_FILENO);
  64. if (fd > STDERR_FILENO)
  65. close(fd);
  66. }
  67. return BOOL_TRUE;
  68. }