/** @file sys.c * @brief System-related faux functions. */ #include #include #include #include #include #include #include #include #include "faux/faux.h" /** Implementation of daemon() function. * * The original daemon() function is not POSIX. Additionally parent doesn't * create PID file as UNIX services do. So after parent exiting there is no * PID file yet. This function fix that problems. * * @param [in] nochdir On zero changes working dir to "/". Compatible with daemon(). * @param [in] noclose On zero redirects standard streams to "/dev/null". Compatible with daemon(). * @param [in] pidfile Name of PID file to create. * @param [in] mode PID file mode. * @return BOOL_TRUE on success, BOOL_FALSE else. * @sa daemon() */ bool_t faux_daemon(int nochdir, int noclose, const char *pidfile, mode_t mode) { pid_t pid = -1; pid = fork(); if (-1 == pid) return BOOL_FALSE; // Parent if (pid > 0) { // Parent writes PID file if (pidfile && (pidfile[0] != '\0')) { int fd = -1; if ((fd = open(pidfile, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, mode)) >= 0) { ssize_t r = 0; char str[20] = {}; snprintf(str, sizeof(str), "%u\n", pid); str[sizeof(str) - 1] = '\0'; r = write(fd, str, strlen(str)); r = r; // Happy compiler close(fd); } } _exit(0); // Exit parent } // Child if (setsid() == -1) return BOOL_FALSE; if (0 == nochdir) { if (chdir("/")) return BOOL_FALSE; } if (0 == noclose) { int fd = -1; fd = open("/dev/null", O_RDWR, 0); if (fd < 0) return BOOL_FALSE; dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); if (fd > STDERR_FILENO) close(fd); } return BOOL_TRUE; }