2 * UCW Library -- Daemon Control
4 * (c) 2012 Martin Mares <mj@ucw.cz>
6 * This software may be freely distributed and used according to the terms
7 * of the GNU Lesser General Public License.
11 #include <ucw/daemon.h>
12 #include <ucw/process.h>
24 static enum daemon_control_status
25 daemon_control_err(struct daemon_control_params *dc, char *msg, ...)
29 vsnprintf(dc->error_msg, DAEMON_ERR_LEN, msg, args);
31 return DAEMON_STATUS_ERROR;
35 daemon_read_pid(struct daemon_control_params *dc, int will_wait, int *stalep)
39 int pid_fd = open(dc->pid_file, O_RDONLY);
44 daemon_control_err(dc, "Cannot open PID file `%s': %m", dc->pid_file);
48 if (flock(pid_fd, LOCK_EX | (will_wait ? 0 : LOCK_NB)) >= 0)
50 // The lock file is stale
56 if (errno != EINTR && errno != EWOULDBLOCK)
58 daemon_control_err(dc, "Cannot lock PID file `%s': %m", dc->pid_file);
63 int n = read(pid_fd, buf, sizeof(buf));
66 daemon_control_err(dc, "Error reading `%s': %m", dc->pid_file);
69 if (n == (int) sizeof(buf))
71 daemon_control_err(dc, "PID file `%s' is too long", dc->pid_file);
78 daemon_control_err(dc, "PID file `%s' does not contain a valid PID", dc->pid_file);
89 enum daemon_control_status
90 daemon_control(struct daemon_control_params *dc)
92 enum daemon_control_status st = DAEMON_STATUS_ERROR;
93 int sig, stale, stale2;
95 int guard_fd = open(dc->guard_file, O_RDWR | O_CREAT, 0666);
97 return daemon_control_err(dc, "Cannot open guard file `%s': %m", dc->guard_file);
98 if (flock(guard_fd, LOCK_EX) < 0)
99 return daemon_control_err(dc, "Cannot lock guard file `%s': %m", dc->guard_file);
102 int pid = daemon_read_pid(dc, 0, &stale);
108 case DAEMON_CONTROL_CHECK:
110 st = DAEMON_STATUS_OK;
112 st = DAEMON_STATUS_STALE;
114 st = DAEMON_STATUS_NOT_RUNNING;
116 case DAEMON_CONTROL_START:
118 st = DAEMON_STATUS_ALREADY_DONE;
124 daemon_control_err(dc, "Cannot fork: %m");
130 execvp(dc->argv[0], dc->argv);
131 fprintf(stderr, "Cannot execute `%s': %m\n", dc->argv[0]);
132 exit(DAEMON_STATUS_ERROR);
135 int ec = waitpid(pp, &stat, 0);
138 daemon_control_err(dc, "Cannot wait: %m");
141 if (WIFEXITED(stat) && WEXITSTATUS(stat) == DAEMON_STATUS_ERROR)
143 daemon_control_err(dc, "Cannot execute the daemon");
146 char ecmsg[EXIT_STATUS_MSG_SIZE];
147 if (format_exit_status(ecmsg, stat))
149 daemon_control_err(dc, "Daemon %s %s", dc->argv[0], ecmsg);
152 pid = daemon_read_pid(dc, 0, &stale2);
154 daemon_control_err(dc, "Daemon %s failed to write the PID file `%s'", dc->argv[0], dc->pid_file);
156 st = stale ? DAEMON_STATUS_STALE : DAEMON_STATUS_OK;
159 case DAEMON_CONTROL_STOP:
161 return stale ? DAEMON_STATUS_STALE : DAEMON_STATUS_ALREADY_DONE;
162 sig = dc->signal ? : SIGTERM;
163 if (kill(pid, sig) < 0)
165 daemon_control_err(dc, "Cannot send signal %d: %m", sig);
168 pid = daemon_read_pid(dc, 1, &stale2);
171 st = DAEMON_STATUS_OK;
173 case DAEMON_CONTROL_SIGNAL:
175 return DAEMON_STATUS_NOT_RUNNING;
176 sig = dc->signal ? : SIGHUP;
177 if (kill(pid, sig) < 0)
178 daemon_control_err(dc, "Cannot send signal %d: %m", sig);
180 st = DAEMON_STATUS_OK;