23 #ifdef HAVE_SYS_TIME_H
32 #if (0 == SIZEOF_PID_T) && defined(_WIN32)
36 #define PID_T_FORMAT "%d"
37 #elif (SIZEOF_PID_T == SIZEOF_INT) || (SIZEOF_PID_T == SIZEOF_SHORT)
38 #define PID_T_FORMAT "%d"
39 #elif (SIZEOF_PID_T == SIZEOF_LONG)
40 #define PID_T_FORMAT "%ld"
41 #elif (SIZEOF_PID_T == 8)
42 #define PID_T_FORMAT "%"PRId64
44 #error Unknown: SIZEOF_PID_T
49 #define PROCMON_POLLS 1
80 pid_l =
tor_parse_long(process_spec, 10, 1, LONG_MAX, &pid_ok, &pspec_next);
86 if ((*pspec_next != 0) && (*pspec_next !=
' ') && (*pspec_next !=
':')) {
90 ppspec->pid = (pid_t)(pid_l);
91 if (!pid_ok || (pid_l != (
long)(ppspec->pid))) {
148 tor_procmon_callback_t
cb;
169 static const struct timeval poll_interval_tv = {15, 0};
182 const char *process_spec,
184 tor_procmon_callback_t cb,
void *cb_arg,
194 if (procmon == NULL) {
195 *msg =
"out of memory";
204 procmon->
pid = ppspec.pid;
207 procmon->hproc = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE,
211 if (procmon->hproc != NULL) {
212 procmon->poll_hproc = 1;
213 log_info(procmon->
log_domain,
"Successfully opened handle to process "
220 log_info(procmon->
log_domain,
"Failed to open handle to process "
221 PID_T_FORMAT
"; will "
240 tor_process_monitor_free(procmon);
257 if (procmon->poll_hproc) {
259 if (!GetExitCodeProcess(procmon->hproc, &exit_code)) {
260 char *errmsg = format_win32_error(GetLastError());
261 log_warn(procmon->
log_domain,
"Error \"%s\" occurred while polling "
262 "handle for monitored process "PID_T_FORMAT
"; assuming "
264 errmsg, procmon->
pid);
268 its_dead_jim = (exit_code != STILL_ACTIVE);
273 procmon->hproc = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE,
277 if (procmon->hproc != NULL) {
278 log_info(procmon->
log_domain,
"Successfully opened handle to monitored "
279 "process "PID_T_FORMAT
".",
282 procmon->poll_hproc = 1;
284 DWORD err_code = GetLastError();
285 char *errmsg = format_win32_error(err_code);
294 its_dead_jim = (err_code == ERROR_INVALID_PARAMETER);
297 log_info(procmon->
log_domain,
"Failed to open handle to monitored "
298 "process "PID_T_FORMAT
", and error code %lu (%s) is not "
299 "'invalid parameter' -- assuming the process is still alive.",
308 its_dead_jim = kill(procmon->
pid, 0);
309 its_dead_jim = its_dead_jim && (errno == ESRCH);
313 procmon->
log_domain,
"Monitored process "PID_T_FORMAT
" is %s.",
315 its_dead_jim ?
"dead" :
"still alive");
331 if (procmon->hproc != NULL)
332 CloseHandle(procmon->hproc);
335 if (procmon->
e != NULL)
336 periodic_timer_free(procmon->
e);
periodic_timer_t * periodic_timer_new(struct event_base *base, const struct timeval *tv, void(*cb)(periodic_timer_t *timer, void *data), void *data)
void tor_log(int severity, log_domain_mask_t domain, const char *format,...)
uint64_t log_domain_mask_t
Headers for util_malloc.c.
long tor_parse_long(const char *s, int base, long min, long max, int *ok, char **next)
tor_process_monitor_t * tor_process_monitor_new(struct event_base *base, const char *process_spec, log_domain_mask_t log_domain, tor_procmon_callback_t cb, void *cb_arg, const char **msg)
int tor_validate_process_specifier(const char *process_spec, const char **msg)
static int parse_process_specifier(const char *process_spec, struct parsed_process_specifier_t *ppspec, const char **msg)
void tor_process_monitor_free_(tor_process_monitor_t *procmon)
static void tor_process_monitor_poll_cb(periodic_timer_t *ev, void *procmon_)
tor_procmon_callback_t cb
log_domain_mask_t log_domain
Macros to manage assertions, fatal and non-fatal.