| 73 | } |
| 74 | |
| 75 | static void daemonize(const std::string &lockfile, const char *user) { |
| 76 | pid_t pid, sid; |
| 77 | int lfp = -1; |
| 78 | char str[10]; |
| 79 | |
| 80 | // already a daemon |
| 81 | if ( getppid() == 1 ) { |
| 82 | return; |
| 83 | } |
| 84 | |
| 85 | // create the lock file as the current user |
| 86 | // give group 'rw' permission and other users 'r' permissions |
| 87 | if (!lockfile.empty()) { |
| 88 | lfp = open(lockfile.c_str(), O_RDWR | O_CREAT, 0664); |
| 89 | if (lfp < 0) { |
| 90 | printf("unable to create lock file %s, %s (code=%d)\r\n", lockfile.c_str(), strerror(errno), errno); |
| 91 | exit(EXIT_FAILURE); |
| 92 | } |
| 93 | } |
| 94 | // drop current user, and try to run as 'user' |
| 95 | if (user) { |
| 96 | printf("try running as user: %s\r\n", user); |
| 97 | struct passwd *pw = getpwnam(user); |
| 98 | if (pw) { |
| 99 | if (setuid(pw->pw_uid) != 0) { |
| 100 | printf("unable to set uid: %d (%s)\r\n", pw->pw_uid, strerror(errno)); |
| 101 | CLOSE_FD(lfp); |
| 102 | exit(EXIT_FAILURE); |
| 103 | } |
| 104 | } else { |
| 105 | printf("unable to find user: %s\r\n", user); |
| 106 | CLOSE_FD(lfp); |
| 107 | exit(EXIT_FAILURE); |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | // trap signals that we expect to receive |
| 112 | signal(SIGCHLD, child_handler); |
| 113 | signal(SIGUSR1, child_handler); |
| 114 | signal(SIGALRM, child_handler); |
| 115 | signal(SIGTERM, child_handler); |
| 116 | signal(SIGHUP, child_handler); |
| 117 | signal(SIGKILL, child_handler); |
| 118 | signal(SIGINT, child_handler); |
| 119 | |
| 120 | // fork off the parent process |
| 121 | pid = fork(); |
| 122 | if (pid < 0) { |
| 123 | printf("unable to fork daemon, %s (code=%d)\r\n", strerror(errno), errno); |
| 124 | CLOSE_FD(lfp); |
| 125 | exit(EXIT_FAILURE); |
| 126 | } |
| 127 | |
| 128 | // if we got a good PID, then we can exit the parent process |
| 129 | if (pid > 0) { |
| 130 | // Wait for confirmation from the child via SIGUSR1, or |
| 131 | // for two seconds to elapse (SIGALRM) |
| 132 | CLOSE_FD(lfp); |