diff options
author | Nils Durner <durner@gnunet.org> | 2009-06-11 13:39:32 +0000 |
---|---|---|
committer | Nils Durner <durner@gnunet.org> | 2009-06-11 13:39:32 +0000 |
commit | 4dcecfd72005cc8f990dea5fca456da54a6eaa98 (patch) | |
tree | 410234c02cae025f3364dce5bc0dba5735d74bb2 /src | |
parent | ba96830423bfa01596be48f9c9326229a1fc802a (diff) | |
download | gnunet-4dcecfd72005cc8f990dea5fca456da54a6eaa98.tar.gz gnunet-4dcecfd72005cc8f990dea5fca456da54a6eaa98.zip |
poll PIDs for status information
Diffstat (limited to 'src')
-rw-r--r-- | src/arm/gnunet-service-arm.c | 30 | ||||
-rw-r--r-- | src/include/gnunet_os_lib.h | 30 | ||||
-rw-r--r-- | src/util/os_priority.c | 105 |
3 files changed, 151 insertions, 14 deletions
diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c index 4417a68a0..9c302d1de 100644 --- a/src/arm/gnunet-service-arm.c +++ b/src/arm/gnunet-service-arm.c | |||
@@ -549,7 +549,6 @@ maint (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
549 | { | 549 | { |
550 | struct ServiceList *pos; | 550 | struct ServiceList *pos; |
551 | pid_t pid; | 551 | pid_t pid; |
552 | int status; | ||
553 | const char *statstr; | 552 | const char *statstr; |
554 | int statcode; | 553 | int statcode; |
555 | struct stat sbuf; | 554 | struct stat sbuf; |
@@ -562,7 +561,7 @@ maint (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
562 | running = pos->next; | 561 | running = pos->next; |
563 | if (0 != PLIBC_KILL (pos->pid, SIGTERM)) | 562 | if (0 != PLIBC_KILL (pos->pid, SIGTERM)) |
564 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); | 563 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); |
565 | if (pos->pid != waitpid (pos->pid, NULL, 0)) | 564 | if (GNUNET_OK != GNUNET_OS_process_wait(pos->pid)) |
566 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); | 565 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); |
567 | free_entry (pos); | 566 | free_entry (pos); |
568 | } | 567 | } |
@@ -575,25 +574,28 @@ maint (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
575 | MAINT_FREQUENCY, &maint, cfg); | 574 | MAINT_FREQUENCY, &maint, cfg); |
576 | 575 | ||
577 | /* check for services that died (WAITPID) */ | 576 | /* check for services that died (WAITPID) */ |
578 | while (0 < (pid = waitpid (0, &status, WNOHANG))) | 577 | for (pos = running; pos != NULL; pos = pos->next) |
579 | { | 578 | { |
580 | if (WIFSTOPPED (status) || WIFCONTINUED (status)) | 579 | enum GNUNET_OS_ProcessStatusType statusType; |
580 | unsigned long statusCode; | ||
581 | |||
582 | if (GNUNET_OS_process_status(pos->pid, &statusType, &statusCode) != GNUNET_OK) | ||
583 | { | ||
584 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "GNUNET_OS_process_status"); | ||
581 | continue; | 585 | continue; |
582 | pos = find_pid (pid); | 586 | } |
583 | if (pos == NULL) | 587 | |
584 | { | 588 | if (statusType == GNUNET_OS_PROCESS_STOPPED || statusType == GNUNET_OS_PROCESS_RUNNING) |
585 | /* we killed the service */ | 589 | continue; |
586 | continue; | 590 | else if (statusType == GNUNET_OS_PROCESS_EXITED) |
587 | } | ||
588 | if (WIFEXITED (status)) | ||
589 | { | 591 | { |
590 | statstr = _( /* process termination method */ "exit"); | 592 | statstr = _( /* process termination method */ "exit"); |
591 | statcode = WEXITSTATUS (status); | 593 | statcode = statusCode; |
592 | } | 594 | } |
593 | else if (WTERMSIG (status)) | 595 | else if (statusType == GNUNET_OS_PROCESS_SIGNALED) |
594 | { | 596 | { |
595 | statstr = _( /* process termination method */ "signal"); | 597 | statstr = _( /* process termination method */ "signal"); |
596 | statcode = WTERMSIG (status); | 598 | statcode = statusCode; |
597 | } | 599 | } |
598 | else | 600 | else |
599 | { | 601 | { |
diff --git a/src/include/gnunet_os_lib.h b/src/include/gnunet_os_lib.h index dfab4a747..8e48a049c 100644 --- a/src/include/gnunet_os_lib.h +++ b/src/include/gnunet_os_lib.h | |||
@@ -60,6 +60,19 @@ enum GNUNET_OS_InstallationPathKind | |||
60 | 60 | ||
61 | 61 | ||
62 | /** | 62 | /** |
63 | * Process status types | ||
64 | */ | ||
65 | enum GNUNET_OS_ProcessStatusType | ||
66 | { | ||
67 | GNUNET_OS_PROCESS_UNKNOWN, | ||
68 | GNUNET_OS_PROCESS_RUNNING, | ||
69 | GNUNET_OS_PROCESS_STOPPED, | ||
70 | GNUNET_OS_PROCESS_EXITED, | ||
71 | GNUNET_OS_PROCESS_SIGNALED | ||
72 | }; | ||
73 | |||
74 | |||
75 | /** | ||
63 | * Get the path to a specific GNUnet installation directory or, with | 76 | * Get the path to a specific GNUnet installation directory or, with |
64 | * GNUNET_OS_IPK_SELF_PREFIX, the current running apps installation | 77 | * GNUNET_OS_IPK_SELF_PREFIX, the current running apps installation |
65 | * directory. | 78 | * directory. |
@@ -145,6 +158,23 @@ pid_t GNUNET_OS_start_process (const char *filename, ...); | |||
145 | */ | 158 | */ |
146 | pid_t GNUNET_OS_start_process_v (const char *filename, char *const argv[]); | 159 | pid_t GNUNET_OS_start_process_v (const char *filename, char *const argv[]); |
147 | 160 | ||
161 | /** | ||
162 | * Retrieve the status of a process | ||
163 | * @param proc process ID | ||
164 | * @param type status type | ||
165 | * @param code return code/signal number | ||
166 | * @return GNUNET_OK on success, GNUNET_SYSERR otherwise | ||
167 | */ | ||
168 | int GNUNET_OS_process_status (pid_t proc, enum GNUNET_OS_ProcessStatusType *type, | ||
169 | unsigned long *code); | ||
170 | |||
171 | /** | ||
172 | * Wait for a process | ||
173 | * @param proc process ID to wait for | ||
174 | * @return GNUNET_OK on success, GNUNET_SYSERR otherwise | ||
175 | */ | ||
176 | int GNUNET_OS_process_wait (pid_t proc); | ||
177 | |||
148 | #if 0 /* keep Emacsens' auto-indent happy */ | 178 | #if 0 /* keep Emacsens' auto-indent happy */ |
149 | { | 179 | { |
150 | #endif | 180 | #endif |
diff --git a/src/util/os_priority.c b/src/util/os_priority.c index f74bd9266..c017a1e38 100644 --- a/src/util/os_priority.c +++ b/src/util/os_priority.c | |||
@@ -257,9 +257,114 @@ GNUNET_OS_start_process_v (const char *filename, char *const argv[]) | |||
257 | #endif | 257 | #endif |
258 | } | 258 | } |
259 | 259 | ||
260 | /** | ||
261 | * Retrieve the status of a process | ||
262 | * @param proc process ID | ||
263 | * @param type status type | ||
264 | * @param code return code/signal number | ||
265 | * @return GNUNET_OK on success, GNUNET_SYSERR otherwise | ||
266 | */ | ||
267 | int | ||
268 | GNUNET_OS_process_status (pid_t proc, enum GNUNET_OS_ProcessStatusType *type, | ||
269 | unsigned long *code) | ||
270 | { | ||
271 | #ifndef MINGW | ||
272 | int status; | ||
273 | |||
274 | if (proc != waitpid (0, &status, WNOHANG)) | ||
275 | return GNUNET_SYSERR; | ||
276 | if (WIFEXITED (status)) | ||
277 | { | ||
278 | *type = GNUNET_OS_PROCESS_EXITED; | ||
279 | *code = WEXITSTATUS (status); | ||
280 | } | ||
281 | else if (WIFSIGNALED (status)) | ||
282 | { | ||
283 | *type = GNUNET_OS_PROCESS_SIGNALED; | ||
284 | *code = WTERMSIG (status); | ||
285 | } | ||
286 | else if (WIFSTOPPED (status)) | ||
287 | { | ||
288 | *type = GNUNET_OS_PROCESS_SIGNALED; | ||
289 | *code = WSTOPSIG (status); | ||
290 | } | ||
291 | else if (WIFCONTINUED (status)) | ||
292 | { | ||
293 | *type = GNUNET_OS_PROCESS_RUNNING; | ||
294 | *code = 0; | ||
295 | } | ||
296 | else | ||
297 | { | ||
298 | *type = GNUNET_OS_PROCESS_UNKNOWN; | ||
299 | *code = 0; | ||
300 | } | ||
301 | #else | ||
302 | HANDLE h; | ||
303 | DWORD c; | ||
304 | |||
305 | h = OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, proc); | ||
306 | if (INVALID_HANDLE_VALUE == h) | ||
307 | { | ||
308 | SetErrnoFromWinError (GetLastError ()); | ||
309 | return GNUNET_SYSERR; | ||
310 | } | ||
311 | |||
312 | c = GetExitCodeProcess (proc, &c); | ||
313 | if (STILL_ACTIVE == c) | ||
314 | { | ||
315 | *type = GNUNET_OS_PROCESS_RUNNING; | ||
316 | *code = 0; | ||
317 | } | ||
318 | else | ||
319 | { | ||
320 | *type = GNUNET_OS_PROCESS_EXITED; | ||
321 | *code = c; | ||
322 | } | ||
323 | |||
324 | CloseHandle (h); | ||
325 | #endif | ||
326 | |||
327 | return GNUNET_OK; | ||
328 | } | ||
329 | |||
330 | /** | ||
331 | * Wait for a process | ||
332 | * @param proc process ID to wait for | ||
333 | * @return GNUNET_OK on success, GNUNET_SYSERR otherwise | ||
334 | */ | ||
335 | int | ||
336 | GNUNET_OS_process_wait (pid_t proc) | ||
337 | { | ||
338 | #ifndef MINGW | ||
339 | if (proc != waitpid (proc, NULL, 0)) | ||
340 | return GNUNET_SYSERR; | ||
260 | 341 | ||
342 | return GNUNET_OK; | ||
343 | #else | ||
344 | HANDLE h; | ||
345 | DWORD c; | ||
346 | int ret; | ||
261 | 347 | ||
348 | h = OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, proc); | ||
349 | if (INVALID_HANDLE_VALUE == h) | ||
350 | { | ||
351 | SetErrnoFromWinError (GetLastError ()); | ||
352 | return GNUNET_SYSERR; | ||
353 | } | ||
262 | 354 | ||
355 | if (WAIT_OBJECT_0 != WaitForSingleObject (h, INFINITE)) | ||
356 | { | ||
357 | SetErrnoFromWinError (GetLastError ()); | ||
358 | ret = GNUNET_SYSERR; | ||
359 | } | ||
360 | else | ||
361 | ret = GNUNET_OK; | ||
362 | |||
363 | CloseHandle (h); | ||
364 | |||
365 | return ret; | ||
366 | #endif | ||
367 | } | ||
263 | 368 | ||
264 | 369 | ||
265 | /* end of os_priority.c */ | 370 | /* end of os_priority.c */ |