aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNils Durner <durner@gnunet.org>2009-06-11 13:39:32 +0000
committerNils Durner <durner@gnunet.org>2009-06-11 13:39:32 +0000
commit4dcecfd72005cc8f990dea5fca456da54a6eaa98 (patch)
tree410234c02cae025f3364dce5bc0dba5735d74bb2 /src
parentba96830423bfa01596be48f9c9326229a1fc802a (diff)
downloadgnunet-4dcecfd72005cc8f990dea5fca456da54a6eaa98.tar.gz
gnunet-4dcecfd72005cc8f990dea5fca456da54a6eaa98.zip
poll PIDs for status information
Diffstat (limited to 'src')
-rw-r--r--src/arm/gnunet-service-arm.c30
-rw-r--r--src/include/gnunet_os_lib.h30
-rw-r--r--src/util/os_priority.c105
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 */
65enum 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 */
146pid_t GNUNET_OS_start_process_v (const char *filename, char *const argv[]); 159pid_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 */
168int 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 */
176int 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 */
267int
268GNUNET_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 */
335int
336GNUNET_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 */