diff options
Diffstat (limited to 'src/arm/gnunet-service-arm.c')
-rw-r--r-- | src/arm/gnunet-service-arm.c | 2359 |
1 files changed, 1216 insertions, 1143 deletions
diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c index e02314b91..d13be6eb1 100644 --- a/src/arm/gnunet-service-arm.c +++ b/src/arm/gnunet-service-arm.c | |||
@@ -29,10 +29,10 @@ | |||
29 | #include "gnunet_protocols.h" | 29 | #include "gnunet_protocols.h" |
30 | #include "arm.h" | 30 | #include "arm.h" |
31 | 31 | ||
32 | #define LOG(kind, ...) GNUNET_log_from(kind, "util", __VA_ARGS__) | 32 | #define LOG(kind, ...) GNUNET_log_from (kind, "util", __VA_ARGS__) |
33 | 33 | ||
34 | #define LOG_STRERROR(kind, syscall) \ | 34 | #define LOG_STRERROR(kind, syscall) \ |
35 | GNUNET_log_from_strerror(kind, "util", syscall) | 35 | GNUNET_log_from_strerror (kind, "util", syscall) |
36 | 36 | ||
37 | 37 | ||
38 | #if HAVE_WAIT4 | 38 | #if HAVE_WAIT4 |
@@ -65,7 +65,8 @@ struct ServiceList; | |||
65 | /** | 65 | /** |
66 | * Record with information about a listen socket we have open. | 66 | * Record with information about a listen socket we have open. |
67 | */ | 67 | */ |
68 | struct ServiceListeningInfo { | 68 | struct ServiceListeningInfo |
69 | { | ||
69 | /** | 70 | /** |
70 | * This is a linked list. | 71 | * This is a linked list. |
71 | */ | 72 | */ |
@@ -106,7 +107,8 @@ struct ServiceListeningInfo { | |||
106 | /** | 107 | /** |
107 | * List of our services. | 108 | * List of our services. |
108 | */ | 109 | */ |
109 | struct ServiceList { | 110 | struct ServiceList |
111 | { | ||
110 | /** | 112 | /** |
111 | * This is a doubly-linked list. | 113 | * This is a doubly-linked list. |
112 | */ | 114 | */ |
@@ -164,6 +166,11 @@ struct ServiceList { | |||
164 | struct GNUNET_TIME_Relative backoff; | 166 | struct GNUNET_TIME_Relative backoff; |
165 | 167 | ||
166 | /** | 168 | /** |
169 | * Absolute time at which the process was (re-)started last. | ||
170 | */ | ||
171 | struct GNUNET_TIME_Absolute last_started_at; | ||
172 | |||
173 | /** | ||
167 | * Absolute time at which the process is scheduled to restart in case of death | 174 | * Absolute time at which the process is scheduled to restart in case of death |
168 | */ | 175 | */ |
169 | struct GNUNET_TIME_Absolute restart_at; | 176 | struct GNUNET_TIME_Absolute restart_at; |
@@ -186,6 +193,11 @@ struct ServiceList { | |||
186 | * are on Windoze). | 193 | * are on Windoze). |
187 | */ | 194 | */ |
188 | int pipe_control; | 195 | int pipe_control; |
196 | |||
197 | /** | ||
198 | * Last exit status of the process. | ||
199 | */ | ||
200 | int last_exit_status; | ||
189 | }; | 201 | }; |
190 | 202 | ||
191 | /** | 203 | /** |
@@ -278,30 +290,30 @@ static struct GNUNET_NotificationContext *notifier; | |||
278 | * parameter is ignore on systems other than LINUX | 290 | * parameter is ignore on systems other than LINUX |
279 | */ | 291 | */ |
280 | static void | 292 | static void |
281 | add_unixpath(struct sockaddr **saddrs, | 293 | add_unixpath (struct sockaddr **saddrs, |
282 | socklen_t *saddrlens, | 294 | socklen_t *saddrlens, |
283 | const char *unixpath, | 295 | const char *unixpath, |
284 | int abstract) | 296 | int abstract) |
285 | { | 297 | { |
286 | #ifdef AF_UNIX | 298 | #ifdef AF_UNIX |
287 | struct sockaddr_un *un; | 299 | struct sockaddr_un *un; |
288 | 300 | ||
289 | un = GNUNET_new(struct sockaddr_un); | 301 | un = GNUNET_new (struct sockaddr_un); |
290 | un->sun_family = AF_UNIX; | 302 | un->sun_family = AF_UNIX; |
291 | GNUNET_strlcpy(un->sun_path, unixpath, sizeof(un->sun_path)); | 303 | GNUNET_strlcpy (un->sun_path, unixpath, sizeof(un->sun_path)); |
292 | #ifdef LINUX | 304 | #ifdef LINUX |
293 | if (GNUNET_YES == abstract) | 305 | if (GNUNET_YES == abstract) |
294 | un->sun_path[0] = '\0'; | 306 | un->sun_path[0] = '\0'; |
295 | #endif | 307 | #endif |
296 | #if HAVE_SOCKADDR_UN_SUN_LEN | 308 | #if HAVE_SOCKADDR_UN_SUN_LEN |
297 | un->sun_len = (u_char)sizeof(struct sockaddr_un); | 309 | un->sun_len = (u_char) sizeof(struct sockaddr_un); |
298 | #endif | 310 | #endif |
299 | *saddrs = (struct sockaddr *)un; | 311 | *saddrs = (struct sockaddr *) un; |
300 | *saddrlens = sizeof(struct sockaddr_un); | 312 | *saddrlens = sizeof(struct sockaddr_un); |
301 | #else | 313 | #else |
302 | /* this function should never be called | 314 | /* this function should never be called |
303 | * unless AF_UNIX is defined! */ | 315 | * unless AF_UNIX is defined! */ |
304 | GNUNET_assert(0); | 316 | GNUNET_assert (0); |
305 | #endif | 317 | #endif |
306 | } | 318 | } |
307 | 319 | ||
@@ -327,10 +339,10 @@ add_unixpath(struct sockaddr **saddrs, | |||
327 | * set to NULL). | 339 | * set to NULL). |
328 | */ | 340 | */ |
329 | static int | 341 | static int |
330 | get_server_addresses(const char *service_name, | 342 | get_server_addresses (const char *service_name, |
331 | const struct GNUNET_CONFIGURATION_Handle *cfg, | 343 | const struct GNUNET_CONFIGURATION_Handle *cfg, |
332 | struct sockaddr ***addrs, | 344 | struct sockaddr ***addrs, |
333 | socklen_t **addr_lens) | 345 | socklen_t **addr_lens) |
334 | { | 346 | { |
335 | int disablev6; | 347 | int disablev6; |
336 | struct GNUNET_NETWORK_Handle *desc; | 348 | struct GNUNET_NETWORK_Handle *desc; |
@@ -351,72 +363,72 @@ get_server_addresses(const char *service_name, | |||
351 | *addrs = NULL; | 363 | *addrs = NULL; |
352 | *addr_lens = NULL; | 364 | *addr_lens = NULL; |
353 | desc = NULL; | 365 | desc = NULL; |
354 | if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "DISABLEV6")) | 366 | if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "DISABLEV6")) |
355 | { | 367 | { |
356 | if (GNUNET_SYSERR == | 368 | if (GNUNET_SYSERR == |
357 | (disablev6 = GNUNET_CONFIGURATION_get_value_yesno(cfg, | 369 | (disablev6 = GNUNET_CONFIGURATION_get_value_yesno (cfg, |
358 | service_name, | 370 | service_name, |
359 | "DISABLEV6"))) | 371 | "DISABLEV6"))) |
360 | return GNUNET_SYSERR; | 372 | return GNUNET_SYSERR; |
361 | } | 373 | } |
362 | else | 374 | else |
363 | disablev6 = GNUNET_NO; | 375 | disablev6 = GNUNET_NO; |
364 | 376 | ||
365 | if (!disablev6) | 377 | if (! disablev6) |
378 | { | ||
379 | /* probe IPv6 support */ | ||
380 | desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0); | ||
381 | if (NULL == desc) | ||
366 | { | 382 | { |
367 | /* probe IPv6 support */ | 383 | if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) || |
368 | desc = GNUNET_NETWORK_socket_create(PF_INET6, SOCK_STREAM, 0); | 384 | (EACCES == errno)) |
369 | if (NULL == desc) | 385 | { |
370 | { | 386 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket"); |
371 | if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) || | 387 | return GNUNET_SYSERR; |
372 | (EACCES == errno)) | 388 | } |
373 | { | 389 | LOG (GNUNET_ERROR_TYPE_INFO, |
374 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "socket"); | 390 | _ ( |
375 | return GNUNET_SYSERR; | 391 | "Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"), |
376 | } | 392 | service_name, |
377 | LOG(GNUNET_ERROR_TYPE_INFO, | 393 | strerror (errno)); |
378 | _( | 394 | disablev6 = GNUNET_YES; |
379 | "Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"), | ||
380 | service_name, | ||
381 | strerror(errno)); | ||
382 | disablev6 = GNUNET_YES; | ||
383 | } | ||
384 | else | ||
385 | { | ||
386 | GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(desc)); | ||
387 | desc = NULL; | ||
388 | } | ||
389 | } | 395 | } |
396 | else | ||
397 | { | ||
398 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc)); | ||
399 | desc = NULL; | ||
400 | } | ||
401 | } | ||
390 | 402 | ||
391 | port = 0; | 403 | port = 0; |
392 | if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "PORT")) | 404 | if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT")) |
405 | { | ||
406 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, | ||
407 | service_name, | ||
408 | "PORT", | ||
409 | &port)) | ||
393 | { | 410 | { |
394 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number(cfg, | 411 | LOG (GNUNET_ERROR_TYPE_ERROR, |
395 | service_name, | 412 | _ ("Require valid port number for service `%s' in configuration!\n"), |
396 | "PORT", | 413 | service_name); |
397 | &port)) | ||
398 | { | ||
399 | LOG(GNUNET_ERROR_TYPE_ERROR, | ||
400 | _("Require valid port number for service `%s' in configuration!\n"), | ||
401 | service_name); | ||
402 | } | ||
403 | if (port > 65535) | ||
404 | { | ||
405 | LOG(GNUNET_ERROR_TYPE_ERROR, | ||
406 | _("Require valid port number for service `%s' in configuration!\n"), | ||
407 | service_name); | ||
408 | return GNUNET_SYSERR; | ||
409 | } | ||
410 | } | 414 | } |
411 | 415 | if (port > 65535) | |
412 | if (GNUNET_CONFIGURATION_have_value(cfg, service_name, "BINDTO")) | ||
413 | { | 416 | { |
414 | GNUNET_break(GNUNET_OK == | 417 | LOG (GNUNET_ERROR_TYPE_ERROR, |
415 | GNUNET_CONFIGURATION_get_value_string(cfg, | 418 | _ ("Require valid port number for service `%s' in configuration!\n"), |
419 | service_name); | ||
420 | return GNUNET_SYSERR; | ||
421 | } | ||
422 | } | ||
423 | |||
424 | if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "BINDTO")) | ||
425 | { | ||
426 | GNUNET_break (GNUNET_OK == | ||
427 | GNUNET_CONFIGURATION_get_value_string (cfg, | ||
416 | service_name, | 428 | service_name, |
417 | "BINDTO", | 429 | "BINDTO", |
418 | &hostname)); | 430 | &hostname)); |
419 | } | 431 | } |
420 | else | 432 | else |
421 | hostname = NULL; | 433 | hostname = NULL; |
422 | 434 | ||
@@ -424,235 +436,235 @@ get_server_addresses(const char *service_name, | |||
424 | abstract = GNUNET_NO; | 436 | abstract = GNUNET_NO; |
425 | #ifdef AF_UNIX | 437 | #ifdef AF_UNIX |
426 | if ((GNUNET_YES == | 438 | if ((GNUNET_YES == |
427 | GNUNET_CONFIGURATION_have_value(cfg, service_name, "UNIXPATH")) && | 439 | GNUNET_CONFIGURATION_have_value (cfg, service_name, "UNIXPATH")) && |
428 | (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename(cfg, | 440 | (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename (cfg, |
429 | service_name, | 441 | service_name, |
430 | "UNIXPATH", | 442 | "UNIXPATH", |
431 | &unixpath)) && | 443 | &unixpath)) && |
432 | (0 < strlen(unixpath))) | 444 | (0 < strlen (unixpath))) |
433 | { | 445 | { |
434 | /* probe UNIX support */ | 446 | /* probe UNIX support */ |
435 | struct sockaddr_un s_un; | 447 | struct sockaddr_un s_un; |
436 | 448 | ||
437 | if (strlen(unixpath) >= sizeof(s_un.sun_path)) | 449 | if (strlen (unixpath) >= sizeof(s_un.sun_path)) |
438 | { | 450 | { |
439 | LOG(GNUNET_ERROR_TYPE_WARNING, | 451 | LOG (GNUNET_ERROR_TYPE_WARNING, |
440 | _("UNIXPATH `%s' too long, maximum length is %llu\n"), | 452 | _ ("UNIXPATH `%s' too long, maximum length is %llu\n"), |
441 | unixpath, | 453 | unixpath, |
442 | (unsigned long long)sizeof(s_un.sun_path)); | 454 | (unsigned long long) sizeof(s_un.sun_path)); |
443 | unixpath = GNUNET_NETWORK_shorten_unixpath(unixpath); | 455 | unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath); |
444 | LOG(GNUNET_ERROR_TYPE_INFO, _("Using `%s' instead\n"), unixpath); | 456 | LOG (GNUNET_ERROR_TYPE_INFO, _ ("Using `%s' instead\n"), unixpath); |
445 | } | 457 | } |
446 | #ifdef LINUX | 458 | #ifdef LINUX |
447 | abstract = GNUNET_CONFIGURATION_get_value_yesno(cfg, | 459 | abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg, |
448 | "TESTING", | 460 | "TESTING", |
449 | "USE_ABSTRACT_SOCKETS"); | 461 | "USE_ABSTRACT_SOCKETS"); |
450 | if (GNUNET_SYSERR == abstract) | 462 | if (GNUNET_SYSERR == abstract) |
451 | abstract = GNUNET_NO; | 463 | abstract = GNUNET_NO; |
452 | #endif | 464 | #endif |
453 | if ((GNUNET_YES != abstract) && | 465 | if ((GNUNET_YES != abstract) && |
454 | (GNUNET_OK != GNUNET_DISK_directory_create_for_file(unixpath))) | 466 | (GNUNET_OK != GNUNET_DISK_directory_create_for_file (unixpath))) |
455 | GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_ERROR, "mkdir", unixpath); | 467 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "mkdir", unixpath); |
456 | } | 468 | } |
457 | if (NULL != unixpath) | 469 | if (NULL != unixpath) |
470 | { | ||
471 | desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0); | ||
472 | if (NULL == desc) | ||
458 | { | 473 | { |
459 | desc = GNUNET_NETWORK_socket_create(AF_UNIX, SOCK_STREAM, 0); | 474 | if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) || |
460 | if (NULL == desc) | 475 | (EACCES == errno)) |
461 | { | 476 | { |
462 | if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) || | 477 | LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket"); |
463 | (EACCES == errno)) | 478 | GNUNET_free_non_null (hostname); |
464 | { | 479 | GNUNET_free (unixpath); |
465 | LOG_STRERROR(GNUNET_ERROR_TYPE_ERROR, "socket"); | 480 | return GNUNET_SYSERR; |
466 | GNUNET_free_non_null(hostname); | 481 | } |
467 | GNUNET_free(unixpath); | 482 | LOG (GNUNET_ERROR_TYPE_INFO, |
468 | return GNUNET_SYSERR; | 483 | _ ( |
469 | } | 484 | "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"), |
470 | LOG(GNUNET_ERROR_TYPE_INFO, | 485 | service_name, |
471 | _( | 486 | strerror (errno)); |
472 | "Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"), | 487 | GNUNET_free (unixpath); |
473 | service_name, | 488 | unixpath = NULL; |
474 | strerror(errno)); | 489 | } |
475 | GNUNET_free(unixpath); | 490 | else |
476 | unixpath = NULL; | 491 | { |
477 | } | 492 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc)); |
478 | else | 493 | desc = NULL; |
479 | { | ||
480 | GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(desc)); | ||
481 | desc = NULL; | ||
482 | } | ||
483 | } | 494 | } |
495 | } | ||
484 | #endif | 496 | #endif |
485 | 497 | ||
486 | if ((0 == port) && (NULL == unixpath)) | 498 | if ((0 == port) && (NULL == unixpath)) |
499 | { | ||
500 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (cfg, | ||
501 | service_name, | ||
502 | "START_ON_DEMAND")) | ||
503 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
504 | _ ( | ||
505 | "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"), | ||
506 | service_name); | ||
507 | GNUNET_free_non_null (hostname); | ||
508 | return GNUNET_SYSERR; | ||
509 | } | ||
510 | if (0 == port) | ||
511 | { | ||
512 | saddrs = GNUNET_new_array (2, struct sockaddr *); | ||
513 | saddrlens = GNUNET_new_array (2, socklen_t); | ||
514 | add_unixpath (saddrs, saddrlens, unixpath, abstract); | ||
515 | GNUNET_free_non_null (unixpath); | ||
516 | GNUNET_free_non_null (hostname); | ||
517 | *addrs = saddrs; | ||
518 | *addr_lens = saddrlens; | ||
519 | return 1; | ||
520 | } | ||
521 | |||
522 | if (NULL != hostname) | ||
523 | { | ||
524 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
525 | "Resolving `%s' since that is where `%s' will bind to.\n", | ||
526 | hostname, | ||
527 | service_name); | ||
528 | memset (&hints, 0, sizeof(struct addrinfo)); | ||
529 | if (disablev6) | ||
530 | hints.ai_family = AF_INET; | ||
531 | hints.ai_protocol = IPPROTO_TCP; | ||
532 | if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) || | ||
533 | (NULL == res)) | ||
487 | { | 534 | { |
488 | if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno(cfg, | 535 | LOG (GNUNET_ERROR_TYPE_ERROR, |
489 | service_name, | 536 | _ ("Failed to resolve `%s': %s\n"), |
490 | "START_ON_DEMAND")) | 537 | hostname, |
491 | LOG(GNUNET_ERROR_TYPE_ERROR, | 538 | gai_strerror (ret)); |
492 | _( | 539 | GNUNET_free (hostname); |
493 | "Have neither PORT nor UNIXPATH for service `%s', but one is required\n"), | 540 | GNUNET_free_non_null (unixpath); |
494 | service_name); | ||
495 | GNUNET_free_non_null(hostname); | ||
496 | return GNUNET_SYSERR; | 541 | return GNUNET_SYSERR; |
497 | } | 542 | } |
498 | if (0 == port) | 543 | next = res; |
544 | i = 0; | ||
545 | while (NULL != (pos = next)) | ||
499 | { | 546 | { |
500 | saddrs = GNUNET_new_array(2, struct sockaddr *); | 547 | next = pos->ai_next; |
501 | saddrlens = GNUNET_new_array(2, socklen_t); | 548 | if ((disablev6) && (pos->ai_family == AF_INET6)) |
502 | add_unixpath(saddrs, saddrlens, unixpath, abstract); | 549 | continue; |
503 | GNUNET_free_non_null(unixpath); | 550 | i++; |
504 | GNUNET_free_non_null(hostname); | ||
505 | *addrs = saddrs; | ||
506 | *addr_lens = saddrlens; | ||
507 | return 1; | ||
508 | } | 551 | } |
509 | 552 | if (0 == i) | |
510 | if (NULL != hostname) | ||
511 | { | 553 | { |
512 | LOG(GNUNET_ERROR_TYPE_DEBUG, | 554 | LOG (GNUNET_ERROR_TYPE_ERROR, |
513 | "Resolving `%s' since that is where `%s' will bind to.\n", | 555 | _ ("Failed to find %saddress for `%s'.\n"), |
514 | hostname, | 556 | disablev6 ? "IPv4 " : "", |
515 | service_name); | 557 | hostname); |
516 | memset(&hints, 0, sizeof(struct addrinfo)); | 558 | freeaddrinfo (res); |
517 | if (disablev6) | 559 | GNUNET_free (hostname); |
518 | hints.ai_family = AF_INET; | 560 | GNUNET_free_non_null (unixpath); |
519 | hints.ai_protocol = IPPROTO_TCP; | 561 | return GNUNET_SYSERR; |
520 | if ((0 != (ret = getaddrinfo(hostname, NULL, &hints, &res))) || | 562 | } |
521 | (NULL == res)) | 563 | resi = i; |
522 | { | 564 | if (NULL != unixpath) |
523 | LOG(GNUNET_ERROR_TYPE_ERROR, | 565 | resi++; |
524 | _("Failed to resolve `%s': %s\n"), | 566 | saddrs = GNUNET_new_array (resi + 1, struct sockaddr *); |
525 | hostname, | 567 | saddrlens = GNUNET_new_array (resi + 1, socklen_t); |
526 | gai_strerror(ret)); | 568 | i = 0; |
527 | GNUNET_free(hostname); | 569 | if (NULL != unixpath) |
528 | GNUNET_free_non_null(unixpath); | 570 | { |
529 | return GNUNET_SYSERR; | 571 | add_unixpath (saddrs, saddrlens, unixpath, abstract); |
530 | } | 572 | i++; |
531 | next = res; | 573 | } |
532 | i = 0; | 574 | next = res; |
533 | while (NULL != (pos = next)) | 575 | while (NULL != (pos = next)) |
534 | { | 576 | { |
535 | next = pos->ai_next; | 577 | next = pos->ai_next; |
536 | if ((disablev6) && (pos->ai_family == AF_INET6)) | 578 | if ((disablev6) && (AF_INET6 == pos->ai_family)) |
537 | continue; | 579 | continue; |
538 | i++; | 580 | if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol)) |
539 | } | 581 | continue; /* not TCP */ |
540 | if (0 == i) | 582 | if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype)) |
541 | { | 583 | continue; /* huh? */ |
542 | LOG(GNUNET_ERROR_TYPE_ERROR, | 584 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
543 | _("Failed to find %saddress for `%s'.\n"), | 585 | "Service `%s' will bind to `%s'\n", |
544 | disablev6 ? "IPv4 " : "", | 586 | service_name, |
545 | hostname); | 587 | GNUNET_a2s (pos->ai_addr, pos->ai_addrlen)); |
546 | freeaddrinfo(res); | 588 | if (AF_INET == pos->ai_family) |
547 | GNUNET_free(hostname); | 589 | { |
548 | GNUNET_free_non_null(unixpath); | 590 | GNUNET_assert (sizeof(struct sockaddr_in) == pos->ai_addrlen); |
549 | return GNUNET_SYSERR; | 591 | saddrlens[i] = pos->ai_addrlen; |
550 | } | 592 | saddrs[i] = GNUNET_malloc (saddrlens[i]); |
551 | resi = i; | 593 | GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]); |
594 | ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); | ||
595 | } | ||
596 | else | ||
597 | { | ||
598 | GNUNET_assert (AF_INET6 == pos->ai_family); | ||
599 | GNUNET_assert (sizeof(struct sockaddr_in6) == pos->ai_addrlen); | ||
600 | saddrlens[i] = pos->ai_addrlen; | ||
601 | saddrs[i] = GNUNET_malloc (saddrlens[i]); | ||
602 | GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]); | ||
603 | ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port); | ||
604 | } | ||
605 | i++; | ||
606 | } | ||
607 | GNUNET_free (hostname); | ||
608 | freeaddrinfo (res); | ||
609 | resi = i; | ||
610 | } | ||
611 | else | ||
612 | { | ||
613 | /* will bind against everything, just set port */ | ||
614 | if (disablev6) | ||
615 | { | ||
616 | /* V4-only */ | ||
617 | resi = 1; | ||
552 | if (NULL != unixpath) | 618 | if (NULL != unixpath) |
553 | resi++; | 619 | resi++; |
554 | saddrs = GNUNET_new_array(resi + 1, struct sockaddr *); | ||
555 | saddrlens = GNUNET_new_array(resi + 1, socklen_t); | ||
556 | i = 0; | 620 | i = 0; |
621 | saddrs = GNUNET_new_array (resi + 1, struct sockaddr *); | ||
622 | saddrlens = GNUNET_new_array (resi + 1, socklen_t); | ||
557 | if (NULL != unixpath) | 623 | if (NULL != unixpath) |
558 | { | 624 | { |
559 | add_unixpath(saddrs, saddrlens, unixpath, abstract); | 625 | add_unixpath (saddrs, saddrlens, unixpath, abstract); |
560 | i++; | 626 | i++; |
561 | } | 627 | } |
562 | next = res; | 628 | saddrlens[i] = sizeof(struct sockaddr_in); |
563 | while (NULL != (pos = next)) | 629 | saddrs[i] = GNUNET_malloc (saddrlens[i]); |
564 | { | ||
565 | next = pos->ai_next; | ||
566 | if ((disablev6) && (AF_INET6 == pos->ai_family)) | ||
567 | continue; | ||
568 | if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol)) | ||
569 | continue; /* not TCP */ | ||
570 | if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype)) | ||
571 | continue; /* huh? */ | ||
572 | LOG(GNUNET_ERROR_TYPE_DEBUG, | ||
573 | "Service `%s' will bind to `%s'\n", | ||
574 | service_name, | ||
575 | GNUNET_a2s(pos->ai_addr, pos->ai_addrlen)); | ||
576 | if (AF_INET == pos->ai_family) | ||
577 | { | ||
578 | GNUNET_assert(sizeof(struct sockaddr_in) == pos->ai_addrlen); | ||
579 | saddrlens[i] = pos->ai_addrlen; | ||
580 | saddrs[i] = GNUNET_malloc(saddrlens[i]); | ||
581 | GNUNET_memcpy(saddrs[i], pos->ai_addr, saddrlens[i]); | ||
582 | ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port); | ||
583 | } | ||
584 | else | ||
585 | { | ||
586 | GNUNET_assert(AF_INET6 == pos->ai_family); | ||
587 | GNUNET_assert(sizeof(struct sockaddr_in6) == pos->ai_addrlen); | ||
588 | saddrlens[i] = pos->ai_addrlen; | ||
589 | saddrs[i] = GNUNET_malloc(saddrlens[i]); | ||
590 | GNUNET_memcpy(saddrs[i], pos->ai_addr, saddrlens[i]); | ||
591 | ((struct sockaddr_in6 *)saddrs[i])->sin6_port = htons(port); | ||
592 | } | ||
593 | i++; | ||
594 | } | ||
595 | GNUNET_free(hostname); | ||
596 | freeaddrinfo(res); | ||
597 | resi = i; | ||
598 | } | ||
599 | else | ||
600 | { | ||
601 | /* will bind against everything, just set port */ | ||
602 | if (disablev6) | ||
603 | { | ||
604 | /* V4-only */ | ||
605 | resi = 1; | ||
606 | if (NULL != unixpath) | ||
607 | resi++; | ||
608 | i = 0; | ||
609 | saddrs = GNUNET_new_array(resi + 1, struct sockaddr *); | ||
610 | saddrlens = GNUNET_new_array(resi + 1, socklen_t); | ||
611 | if (NULL != unixpath) | ||
612 | { | ||
613 | add_unixpath(saddrs, saddrlens, unixpath, abstract); | ||
614 | i++; | ||
615 | } | ||
616 | saddrlens[i] = sizeof(struct sockaddr_in); | ||
617 | saddrs[i] = GNUNET_malloc(saddrlens[i]); | ||
618 | #if HAVE_SOCKADDR_IN_SIN_LEN | 630 | #if HAVE_SOCKADDR_IN_SIN_LEN |
619 | ((struct sockaddr_in *)saddrs[i])->sin_len = saddrlens[i]; | 631 | ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i]; |
620 | #endif | 632 | #endif |
621 | ((struct sockaddr_in *)saddrs[i])->sin_family = AF_INET; | 633 | ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET; |
622 | ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port); | 634 | ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); |
623 | } | 635 | } |
624 | else | 636 | else |
625 | { | 637 | { |
626 | /* dual stack */ | 638 | /* dual stack */ |
627 | resi = 2; | 639 | resi = 2; |
628 | if (NULL != unixpath) | 640 | if (NULL != unixpath) |
629 | resi++; | 641 | resi++; |
630 | saddrs = GNUNET_new_array(resi + 1, struct sockaddr *); | 642 | saddrs = GNUNET_new_array (resi + 1, struct sockaddr *); |
631 | saddrlens = GNUNET_new_array(resi + 1, socklen_t); | 643 | saddrlens = GNUNET_new_array (resi + 1, socklen_t); |
632 | i = 0; | 644 | i = 0; |
633 | if (NULL != unixpath) | 645 | if (NULL != unixpath) |
634 | { | 646 | { |
635 | add_unixpath(saddrs, saddrlens, unixpath, abstract); | 647 | add_unixpath (saddrs, saddrlens, unixpath, abstract); |
636 | i++; | 648 | i++; |
637 | } | 649 | } |
638 | saddrlens[i] = sizeof(struct sockaddr_in6); | 650 | saddrlens[i] = sizeof(struct sockaddr_in6); |
639 | saddrs[i] = GNUNET_malloc(saddrlens[i]); | 651 | saddrs[i] = GNUNET_malloc (saddrlens[i]); |
640 | #if HAVE_SOCKADDR_IN_SIN_LEN | 652 | #if HAVE_SOCKADDR_IN_SIN_LEN |
641 | ((struct sockaddr_in6 *)saddrs[i])->sin6_len = saddrlens[0]; | 653 | ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0]; |
642 | #endif | 654 | #endif |
643 | ((struct sockaddr_in6 *)saddrs[i])->sin6_family = AF_INET6; | 655 | ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6; |
644 | ((struct sockaddr_in6 *)saddrs[i])->sin6_port = htons(port); | 656 | ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port); |
645 | i++; | 657 | i++; |
646 | saddrlens[i] = sizeof(struct sockaddr_in); | 658 | saddrlens[i] = sizeof(struct sockaddr_in); |
647 | saddrs[i] = GNUNET_malloc(saddrlens[i]); | 659 | saddrs[i] = GNUNET_malloc (saddrlens[i]); |
648 | #if HAVE_SOCKADDR_IN_SIN_LEN | 660 | #if HAVE_SOCKADDR_IN_SIN_LEN |
649 | ((struct sockaddr_in *)saddrs[i])->sin_len = saddrlens[1]; | 661 | ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1]; |
650 | #endif | 662 | #endif |
651 | ((struct sockaddr_in *)saddrs[i])->sin_family = AF_INET; | 663 | ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET; |
652 | ((struct sockaddr_in *)saddrs[i])->sin_port = htons(port); | 664 | ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port); |
653 | } | ||
654 | } | 665 | } |
655 | GNUNET_free_non_null(unixpath); | 666 | } |
667 | GNUNET_free_non_null (unixpath); | ||
656 | *addrs = saddrs; | 668 | *addrs = saddrs; |
657 | *addr_lens = saddrlens; | 669 | *addr_lens = saddrlens; |
658 | return resi; | 670 | return resi; |
@@ -670,19 +682,19 @@ get_server_addresses(const char *service_name, | |||
670 | * @return NULL if it was not found | 682 | * @return NULL if it was not found |
671 | */ | 683 | */ |
672 | static void | 684 | static void |
673 | signal_result(struct GNUNET_SERVICE_Client *client, | 685 | signal_result (struct GNUNET_SERVICE_Client *client, |
674 | const char *name, | 686 | const char *name, |
675 | uint64_t request_id, | 687 | uint64_t request_id, |
676 | enum GNUNET_ARM_Result result) | 688 | enum GNUNET_ARM_Result result) |
677 | { | 689 | { |
678 | struct GNUNET_MQ_Envelope *env; | 690 | struct GNUNET_MQ_Envelope *env; |
679 | struct GNUNET_ARM_ResultMessage *msg; | 691 | struct GNUNET_ARM_ResultMessage *msg; |
680 | 692 | ||
681 | (void)name; | 693 | (void) name; |
682 | env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_ARM_RESULT); | 694 | env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_ARM_RESULT); |
683 | msg->result = htonl(result); | 695 | msg->result = htonl (result); |
684 | msg->arm_msg.request_id = GNUNET_htonll(request_id); | 696 | msg->arm_msg.request_id = GNUNET_htonll (request_id); |
685 | GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(client), env); | 697 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env); |
686 | } | 698 | } |
687 | 699 | ||
688 | 700 | ||
@@ -695,34 +707,34 @@ signal_result(struct GNUNET_SERVICE_Client *client, | |||
695 | * otherwise, send to all clients in the notifier | 707 | * otherwise, send to all clients in the notifier |
696 | */ | 708 | */ |
697 | static void | 709 | static void |
698 | broadcast_status(const char *name, | 710 | broadcast_status (const char *name, |
699 | enum GNUNET_ARM_ServiceStatus status, | 711 | enum GNUNET_ARM_ServiceMonitorStatus status, |
700 | struct GNUNET_SERVICE_Client *unicast) | 712 | struct GNUNET_SERVICE_Client *unicast) |
701 | { | 713 | { |
702 | struct GNUNET_MQ_Envelope *env; | 714 | struct GNUNET_MQ_Envelope *env; |
703 | struct GNUNET_ARM_StatusMessage *msg; | 715 | struct GNUNET_ARM_StatusMessage *msg; |
704 | size_t namelen; | 716 | size_t namelen; |
705 | 717 | ||
706 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 718 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
707 | "Sending status %u of service `%s' to client\n", | 719 | "Sending status %u of service `%s' to client\n", |
708 | (unsigned int)status, | 720 | (unsigned int) status, |
709 | name); | 721 | name); |
710 | namelen = strlen(name) + 1; | 722 | namelen = strlen (name) + 1; |
711 | env = GNUNET_MQ_msg_extra(msg, namelen, GNUNET_MESSAGE_TYPE_ARM_STATUS); | 723 | env = GNUNET_MQ_msg_extra (msg, namelen, GNUNET_MESSAGE_TYPE_ARM_STATUS); |
712 | msg->status = htonl((uint32_t)(status)); | 724 | msg->status = htonl ((uint32_t) (status)); |
713 | GNUNET_memcpy((char *)&msg[1], name, namelen); | 725 | GNUNET_memcpy ((char *) &msg[1], name, namelen); |
714 | if (NULL == unicast) | 726 | if (NULL == unicast) |
715 | { | 727 | { |
716 | if (NULL != notifier) | 728 | if (NULL != notifier) |
717 | GNUNET_notification_context_broadcast(notifier, | 729 | GNUNET_notification_context_broadcast (notifier, |
718 | &msg->header, | 730 | &msg->header, |
719 | GNUNET_YES); | 731 | GNUNET_YES); |
720 | GNUNET_MQ_discard(env); | 732 | GNUNET_MQ_discard (env); |
721 | } | 733 | } |
722 | else | 734 | else |
723 | { | 735 | { |
724 | GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(unicast), env); | 736 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (unicast), env); |
725 | } | 737 | } |
726 | } | 738 | } |
727 | 739 | ||
728 | 740 | ||
@@ -735,9 +747,9 @@ broadcast_status(const char *name, | |||
735 | * being started. 0 if starting was not requested. | 747 | * being started. 0 if starting was not requested. |
736 | */ | 748 | */ |
737 | static void | 749 | static void |
738 | start_process(struct ServiceList *sl, | 750 | start_process (struct ServiceList *sl, |
739 | struct GNUNET_SERVICE_Client *client, | 751 | struct GNUNET_SERVICE_Client *client, |
740 | uint64_t request_id) | 752 | uint64_t request_id) |
741 | { | 753 | { |
742 | char *loprefix; | 754 | char *loprefix; |
743 | char *options; | 755 | char *options; |
@@ -753,191 +765,192 @@ start_process(struct ServiceList *sl, | |||
753 | lsocks = NULL; | 765 | lsocks = NULL; |
754 | ls = 0; | 766 | ls = 0; |
755 | for (sli = sl->listen_head; NULL != sli; sli = sli->next) | 767 | for (sli = sl->listen_head; NULL != sli; sli = sli->next) |
768 | { | ||
769 | GNUNET_array_append (lsocks, | ||
770 | ls, | ||
771 | GNUNET_NETWORK_get_fd (sli->listen_socket)); | ||
772 | if (NULL != sli->accept_task) | ||
756 | { | 773 | { |
757 | GNUNET_array_append(lsocks, | 774 | GNUNET_SCHEDULER_cancel (sli->accept_task); |
758 | ls, | 775 | sli->accept_task = NULL; |
759 | GNUNET_NETWORK_get_fd(sli->listen_socket)); | ||
760 | if (NULL != sli->accept_task) | ||
761 | { | ||
762 | GNUNET_SCHEDULER_cancel(sli->accept_task); | ||
763 | sli->accept_task = NULL; | ||
764 | } | ||
765 | } | 776 | } |
777 | } | ||
766 | 778 | ||
767 | GNUNET_array_append(lsocks, ls, -1); | 779 | GNUNET_array_append (lsocks, ls, -1); |
768 | 780 | ||
769 | /* obtain configuration */ | 781 | /* obtain configuration */ |
770 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, | 782 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, |
771 | sl->name, | 783 | sl->name, |
772 | "PREFIX", | 784 | "PREFIX", |
773 | &loprefix)) | 785 | &loprefix)) |
774 | loprefix = GNUNET_strdup(prefix_command); | 786 | loprefix = GNUNET_strdup (prefix_command); |
775 | else | 787 | else |
776 | loprefix = GNUNET_CONFIGURATION_expand_dollar(cfg, loprefix); | 788 | loprefix = GNUNET_CONFIGURATION_expand_dollar (cfg, loprefix); |
777 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, | 789 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, |
778 | sl->name, | 790 | sl->name, |
779 | "OPTIONS", | 791 | "OPTIONS", |
780 | &options)) | 792 | &options)) |
781 | options = NULL; | 793 | options = NULL; |
782 | else | 794 | else |
783 | options = GNUNET_CONFIGURATION_expand_dollar(cfg, options); | 795 | options = GNUNET_CONFIGURATION_expand_dollar (cfg, options); |
784 | { | 796 | { |
785 | char *new_options; | 797 | char *new_options; |
786 | char *optpos; | 798 | char *optpos; |
787 | char *fin_options; | 799 | char *fin_options; |
788 | 800 | ||
789 | fin_options = GNUNET_strdup(final_option); | 801 | fin_options = GNUNET_strdup (final_option); |
790 | /* replace '{}' with service name */ | 802 | /* replace '{}' with service name */ |
791 | while (NULL != (optpos = strstr(fin_options, "{}"))) | 803 | while (NULL != (optpos = strstr (fin_options, "{}"))) |
792 | { | 804 | { |
793 | /* terminate string at opening parenthesis */ | 805 | /* terminate string at opening parenthesis */ |
794 | *optpos = 0; | 806 | *optpos = 0; |
795 | GNUNET_asprintf(&new_options, | 807 | GNUNET_asprintf (&new_options, |
796 | "%s%s%s", | 808 | "%s%s%s", |
797 | fin_options, | 809 | fin_options, |
798 | sl->name, | 810 | sl->name, |
799 | optpos + 2); | 811 | optpos + 2); |
800 | GNUNET_free(fin_options); | 812 | GNUNET_free (fin_options); |
801 | fin_options = new_options; | 813 | fin_options = new_options; |
802 | } | 814 | } |
803 | if (NULL != options) | 815 | if (NULL != options) |
804 | { | 816 | { |
805 | /* combine "fin_options" with "options" */ | 817 | /* combine "fin_options" with "options" */ |
806 | optpos = options; | 818 | optpos = options; |
807 | GNUNET_asprintf(&options, "%s %s", fin_options, optpos); | 819 | GNUNET_asprintf (&options, "%s %s", fin_options, optpos); |
808 | GNUNET_free(fin_options); | 820 | GNUNET_free (fin_options); |
809 | GNUNET_free(optpos); | 821 | GNUNET_free (optpos); |
810 | } | 822 | } |
811 | else | 823 | else |
812 | { | 824 | { |
813 | /* only have "fin_options", use that */ | 825 | /* only have "fin_options", use that */ |
814 | options = fin_options; | 826 | options = fin_options; |
815 | } | 827 | } |
816 | } | 828 | } |
817 | options = GNUNET_CONFIGURATION_expand_dollar(cfg, options); | 829 | options = GNUNET_CONFIGURATION_expand_dollar (cfg, options); |
818 | use_debug = GNUNET_CONFIGURATION_get_value_yesno(cfg, sl->name, "DEBUG"); | 830 | use_debug = GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name, "DEBUG"); |
819 | { | 831 | { |
820 | const char *service_type = NULL; | 832 | const char *service_type = NULL; |
821 | const char *choices[] = { "GNUNET", "SIMPLE", NULL }; | 833 | const char *choices[] = { "GNUNET", "SIMPLE", NULL }; |
822 | 834 | ||
823 | is_simple_service = GNUNET_NO; | 835 | is_simple_service = GNUNET_NO; |
824 | if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_choice(cfg, | 836 | if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_choice (cfg, |
825 | sl->name, | 837 | sl->name, |
826 | "TYPE", | 838 | "TYPE", |
827 | choices, | 839 | choices, |
828 | &service_type)) && | 840 | &service_type)) && |
829 | (0 == strcasecmp(service_type, "SIMPLE"))) | 841 | (0 == strcasecmp (service_type, "SIMPLE"))) |
830 | is_simple_service = GNUNET_YES; | 842 | is_simple_service = GNUNET_YES; |
831 | } | 843 | } |
832 | 844 | ||
833 | GNUNET_assert(NULL == sl->proc); | 845 | GNUNET_assert (NULL == sl->proc); |
834 | if (GNUNET_YES == is_simple_service) | 846 | if (GNUNET_YES == is_simple_service) |
835 | { | 847 | { |
836 | /* A simple service will receive no GNUnet specific | 848 | /* A simple service will receive no GNUnet specific |
837 | command line options. */ | 849 | command line options. */ |
838 | binary = GNUNET_strdup(sl->binary); | 850 | binary = GNUNET_strdup (sl->binary); |
839 | binary = GNUNET_CONFIGURATION_expand_dollar(cfg, binary); | 851 | binary = GNUNET_CONFIGURATION_expand_dollar (cfg, binary); |
840 | GNUNET_asprintf("edbinary, "\"%s\"", sl->binary); | 852 | GNUNET_asprintf ("edbinary, "\"%s\"", sl->binary); |
841 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 853 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
842 | "Starting simple service `%s' using binary `%s'\n", | 854 | "Starting simple service `%s' using binary `%s'\n", |
843 | sl->name, | 855 | sl->name, |
844 | sl->binary); | 856 | sl->binary); |
845 | /* FIXME: dollar expansion should only be done outside | 857 | /* FIXME: dollar expansion should only be done outside |
846 | * of ''-quoted strings, escaping should be considered. */ | 858 | * of ''-quoted strings, escaping should be considered. */ |
847 | if (NULL != options) | 859 | if (NULL != options) |
848 | options = GNUNET_CONFIGURATION_expand_dollar(cfg, options); | 860 | options = GNUNET_CONFIGURATION_expand_dollar (cfg, options); |
849 | sl->proc = GNUNET_OS_start_process_s(sl->pipe_control, | 861 | sl->proc = GNUNET_OS_start_process_s (sl->pipe_control, |
850 | GNUNET_OS_INHERIT_STD_OUT_AND_ERR, | 862 | GNUNET_OS_INHERIT_STD_OUT_AND_ERR, |
851 | lsocks, | 863 | lsocks, |
852 | loprefix, | 864 | loprefix, |
853 | quotedbinary, | 865 | quotedbinary, |
854 | options, | 866 | options, |
855 | NULL); | 867 | NULL); |
856 | } | 868 | } |
857 | else | 869 | else |
870 | { | ||
871 | /* actually start process */ | ||
872 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
873 | "Starting service `%s' using binary `%s' and configuration `%s'\n", | ||
874 | sl->name, | ||
875 | sl->binary, | ||
876 | sl->config); | ||
877 | binary = GNUNET_OS_get_libexec_binary_path (sl->binary); | ||
878 | GNUNET_asprintf ("edbinary, "\"%s\"", binary); | ||
879 | |||
880 | if (GNUNET_YES == use_debug) | ||
858 | { | 881 | { |
859 | /* actually start process */ | 882 | if (NULL == sl->config) |
860 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 883 | sl->proc = GNUNET_OS_start_process_s (sl->pipe_control, |
861 | "Starting service `%s' using binary `%s' and configuration `%s'\n", | 884 | GNUNET_OS_INHERIT_STD_OUT_AND_ERR, |
862 | sl->name, | 885 | lsocks, |
863 | sl->binary, | 886 | loprefix, |
864 | sl->config); | 887 | quotedbinary, |
865 | binary = GNUNET_OS_get_libexec_binary_path(sl->binary); | 888 | "-L", |
866 | GNUNET_asprintf("edbinary, "\"%s\"", binary); | 889 | "DEBUG", |
867 | 890 | options, | |
868 | if (GNUNET_YES == use_debug) | 891 | NULL); |
869 | { | ||
870 | if (NULL == sl->config) | ||
871 | sl->proc = GNUNET_OS_start_process_s(sl->pipe_control, | ||
872 | GNUNET_OS_INHERIT_STD_OUT_AND_ERR, | ||
873 | lsocks, | ||
874 | loprefix, | ||
875 | quotedbinary, | ||
876 | "-L", | ||
877 | "DEBUG", | ||
878 | options, | ||
879 | NULL); | ||
880 | else | ||
881 | sl->proc = GNUNET_OS_start_process_s(sl->pipe_control, | ||
882 | GNUNET_OS_INHERIT_STD_OUT_AND_ERR, | ||
883 | lsocks, | ||
884 | loprefix, | ||
885 | quotedbinary, | ||
886 | "-c", | ||
887 | sl->config, | ||
888 | "-L", | ||
889 | "DEBUG", | ||
890 | options, | ||
891 | NULL); | ||
892 | } | ||
893 | else | 892 | else |
894 | { | 893 | sl->proc = GNUNET_OS_start_process_s (sl->pipe_control, |
895 | if (NULL == sl->config) | 894 | GNUNET_OS_INHERIT_STD_OUT_AND_ERR, |
896 | sl->proc = GNUNET_OS_start_process_s(sl->pipe_control, | 895 | lsocks, |
897 | GNUNET_OS_INHERIT_STD_OUT_AND_ERR, | 896 | loprefix, |
898 | lsocks, | 897 | quotedbinary, |
899 | loprefix, | 898 | "-c", |
900 | quotedbinary, | 899 | sl->config, |
901 | options, | 900 | "-L", |
902 | NULL); | 901 | "DEBUG", |
903 | else | 902 | options, |
904 | sl->proc = GNUNET_OS_start_process_s(sl->pipe_control, | 903 | NULL); |
905 | GNUNET_OS_INHERIT_STD_OUT_AND_ERR, | ||
906 | lsocks, | ||
907 | loprefix, | ||
908 | quotedbinary, | ||
909 | "-c", | ||
910 | sl->config, | ||
911 | options, | ||
912 | NULL); | ||
913 | } | ||
914 | } | 904 | } |
915 | GNUNET_free(binary); | 905 | else |
916 | GNUNET_free(quotedbinary); | ||
917 | if (NULL == sl->proc) | ||
918 | { | 906 | { |
919 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | 907 | if (NULL == sl->config) |
920 | _("Failed to start service `%s'\n"), | 908 | sl->proc = GNUNET_OS_start_process_s (sl->pipe_control, |
921 | sl->name); | 909 | GNUNET_OS_INHERIT_STD_OUT_AND_ERR, |
922 | if (client) | 910 | lsocks, |
923 | signal_result(client, | 911 | loprefix, |
924 | sl->name, | 912 | quotedbinary, |
925 | request_id, | 913 | options, |
926 | GNUNET_ARM_RESULT_START_FAILED); | 914 | NULL); |
915 | else | ||
916 | sl->proc = GNUNET_OS_start_process_s (sl->pipe_control, | ||
917 | GNUNET_OS_INHERIT_STD_OUT_AND_ERR, | ||
918 | lsocks, | ||
919 | loprefix, | ||
920 | quotedbinary, | ||
921 | "-c", | ||
922 | sl->config, | ||
923 | options, | ||
924 | NULL); | ||
927 | } | 925 | } |
926 | } | ||
927 | GNUNET_free (binary); | ||
928 | GNUNET_free (quotedbinary); | ||
929 | sl->last_started_at = GNUNET_TIME_absolute_get (); | ||
930 | if (NULL == sl->proc) | ||
931 | { | ||
932 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
933 | _ ("Failed to start service `%s'\n"), | ||
934 | sl->name); | ||
935 | if (client) | ||
936 | signal_result (client, | ||
937 | sl->name, | ||
938 | request_id, | ||
939 | GNUNET_ARM_RESULT_START_FAILED); | ||
940 | } | ||
928 | else | 941 | else |
929 | { | 942 | { |
930 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | 943 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
931 | _("Starting service `%s'\n"), | 944 | _ ("Starting service `%s'\n"), |
932 | sl->name); | 945 | sl->name); |
933 | broadcast_status(sl->name, GNUNET_ARM_SERVICE_STARTING, NULL); | 946 | broadcast_status (sl->name, GNUNET_ARM_SERVICE_STARTING, NULL); |
934 | if (client) | 947 | if (client) |
935 | signal_result(client, sl->name, request_id, GNUNET_ARM_RESULT_STARTING); | 948 | signal_result (client, sl->name, request_id, GNUNET_ARM_RESULT_STARTING); |
936 | } | 949 | } |
937 | /* clean up */ | 950 | /* clean up */ |
938 | GNUNET_free(loprefix); | 951 | GNUNET_free (loprefix); |
939 | GNUNET_free(options); | 952 | GNUNET_free (options); |
940 | GNUNET_array_grow(lsocks, ls, 0); | 953 | GNUNET_array_grow (lsocks, ls, 0); |
941 | } | 954 | } |
942 | 955 | ||
943 | 956 | ||
@@ -949,17 +962,17 @@ start_process(struct ServiceList *sl, | |||
949 | * @return NULL if it was not found | 962 | * @return NULL if it was not found |
950 | */ | 963 | */ |
951 | static struct ServiceList * | 964 | static struct ServiceList * |
952 | find_service(const char *name) | 965 | find_service (const char *name) |
953 | { | 966 | { |
954 | struct ServiceList *sl; | 967 | struct ServiceList *sl; |
955 | 968 | ||
956 | sl = running_head; | 969 | sl = running_head; |
957 | while (sl != NULL) | 970 | while (sl != NULL) |
958 | { | 971 | { |
959 | if (0 == strcasecmp(sl->name, name)) | 972 | if (0 == strcasecmp (sl->name, name)) |
960 | return sl; | 973 | return sl; |
961 | sl = sl->next; | 974 | sl = sl->next; |
962 | } | 975 | } |
963 | return NULL; | 976 | return NULL; |
964 | } | 977 | } |
965 | 978 | ||
@@ -971,14 +984,14 @@ find_service(const char *name) | |||
971 | * @param cls callback data, `struct ServiceListeningInfo` describing a listen socket | 984 | * @param cls callback data, `struct ServiceListeningInfo` describing a listen socket |
972 | */ | 985 | */ |
973 | static void | 986 | static void |
974 | accept_connection(void *cls) | 987 | accept_connection (void *cls) |
975 | { | 988 | { |
976 | struct ServiceListeningInfo *sli = cls; | 989 | struct ServiceListeningInfo *sli = cls; |
977 | struct ServiceList *sl = sli->sl; | 990 | struct ServiceList *sl = sli->sl; |
978 | 991 | ||
979 | sli->accept_task = NULL; | 992 | sli->accept_task = NULL; |
980 | GNUNET_assert(GNUNET_NO == in_shutdown); | 993 | GNUNET_assert (GNUNET_NO == in_shutdown); |
981 | start_process(sl, NULL, 0); | 994 | start_process (sl, NULL, 0); |
982 | } | 995 | } |
983 | 996 | ||
984 | 997 | ||
@@ -991,9 +1004,9 @@ accept_connection(void *cls) | |||
991 | * @param sl service entry for the service in question | 1004 | * @param sl service entry for the service in question |
992 | */ | 1005 | */ |
993 | static void | 1006 | static void |
994 | create_listen_socket(struct sockaddr *sa, | 1007 | create_listen_socket (struct sockaddr *sa, |
995 | socklen_t addr_len, | 1008 | socklen_t addr_len, |
996 | struct ServiceList *sl) | 1009 | struct ServiceList *sl) |
997 | { | 1010 | { |
998 | static int on = 1; | 1011 | static int on = 1; |
999 | struct GNUNET_NETWORK_Handle *sock; | 1012 | struct GNUNET_NETWORK_Handle *sock; |
@@ -1003,107 +1016,107 @@ create_listen_socket(struct sockaddr *sa, | |||
1003 | int match_gid; | 1016 | int match_gid; |
1004 | 1017 | ||
1005 | switch (sa->sa_family) | 1018 | switch (sa->sa_family) |
1006 | { | 1019 | { |
1007 | case AF_INET: | 1020 | case AF_INET: |
1008 | sock = GNUNET_NETWORK_socket_create(PF_INET, SOCK_STREAM, 0); | 1021 | sock = GNUNET_NETWORK_socket_create (PF_INET, SOCK_STREAM, 0); |
1009 | break; | 1022 | break; |
1010 | 1023 | ||
1011 | case AF_INET6: | 1024 | case AF_INET6: |
1012 | sock = GNUNET_NETWORK_socket_create(PF_INET6, SOCK_STREAM, 0); | 1025 | sock = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0); |
1013 | break; | 1026 | break; |
1014 | 1027 | ||
1015 | case AF_UNIX: | 1028 | case AF_UNIX: |
1016 | if (0 == strcmp(GNUNET_a2s(sa, addr_len), | 1029 | if (0 == strcmp (GNUNET_a2s (sa, addr_len), |
1017 | "@")) /* Do not bind to blank UNIX path! */ | 1030 | "@")) /* Do not bind to blank UNIX path! */ |
1018 | return; | ||
1019 | sock = GNUNET_NETWORK_socket_create(PF_UNIX, SOCK_STREAM, 0); | ||
1020 | break; | ||
1021 | |||
1022 | default: | ||
1023 | GNUNET_break(0); | ||
1024 | sock = NULL; | ||
1025 | errno = EAFNOSUPPORT; | ||
1026 | break; | ||
1027 | } | ||
1028 | if (NULL == sock) | ||
1029 | { | ||
1030 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
1031 | _("Unable to create socket for service `%s': %s\n"), | ||
1032 | sl->name, | ||
1033 | strerror(errno)); | ||
1034 | GNUNET_free(sa); | ||
1035 | return; | 1031 | return; |
1036 | } | 1032 | sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0); |
1037 | if (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt(sock, | 1033 | break; |
1038 | SOL_SOCKET, | 1034 | |
1039 | SO_REUSEADDR, | 1035 | default: |
1040 | &on, | 1036 | GNUNET_break (0); |
1041 | sizeof(on))) | 1037 | sock = NULL; |
1042 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 1038 | errno = EAFNOSUPPORT; |
1043 | "setsockopt"); | 1039 | break; |
1040 | } | ||
1041 | if (NULL == sock) | ||
1042 | { | ||
1043 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1044 | _ ("Unable to create socket for service `%s': %s\n"), | ||
1045 | sl->name, | ||
1046 | strerror (errno)); | ||
1047 | GNUNET_free (sa); | ||
1048 | return; | ||
1049 | } | ||
1050 | if (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt (sock, | ||
1051 | SOL_SOCKET, | ||
1052 | SO_REUSEADDR, | ||
1053 | &on, | ||
1054 | sizeof(on))) | ||
1055 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
1056 | "setsockopt"); | ||
1044 | #ifdef IPV6_V6ONLY | 1057 | #ifdef IPV6_V6ONLY |
1045 | if ((sa->sa_family == AF_INET6) && | 1058 | if ((sa->sa_family == AF_INET6) && |
1046 | (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt(sock, | 1059 | (GNUNET_OK != GNUNET_NETWORK_socket_setsockopt (sock, |
1047 | IPPROTO_IPV6, | 1060 | IPPROTO_IPV6, |
1048 | IPV6_V6ONLY, | 1061 | IPV6_V6ONLY, |
1049 | &on, | 1062 | &on, |
1050 | sizeof(on)))) | 1063 | sizeof(on)))) |
1051 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | 1064 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, |
1052 | "setsockopt"); | 1065 | "setsockopt"); |
1053 | #endif | 1066 | #endif |
1054 | if (AF_UNIX == sa->sa_family) | 1067 | if (AF_UNIX == sa->sa_family) |
1055 | GNUNET_NETWORK_unix_precheck((struct sockaddr_un *)sa); | 1068 | GNUNET_NETWORK_unix_precheck ((struct sockaddr_un *) sa); |
1056 | if (GNUNET_OK != | 1069 | if (GNUNET_OK != |
1057 | GNUNET_NETWORK_socket_bind(sock, (const struct sockaddr *)sa, addr_len)) | 1070 | GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) sa, addr_len)) |
1058 | { | 1071 | { |
1059 | GNUNET_log( | 1072 | GNUNET_log ( |
1060 | GNUNET_ERROR_TYPE_WARNING, | 1073 | GNUNET_ERROR_TYPE_WARNING, |
1061 | _( | 1074 | _ ( |
1062 | "Unable to bind listening socket for service `%s' to address `%s': %s\n"), | 1075 | "Unable to bind listening socket for service `%s' to address `%s': %s\n"), |
1063 | sl->name, | 1076 | sl->name, |
1064 | GNUNET_a2s(sa, addr_len), | 1077 | GNUNET_a2s (sa, addr_len), |
1065 | strerror(errno)); | 1078 | strerror (errno)); |
1066 | GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(sock)); | 1079 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); |
1067 | GNUNET_free(sa); | 1080 | GNUNET_free (sa); |
1068 | return; | 1081 | return; |
1069 | } | 1082 | } |
1070 | if ((AF_UNIX == sa->sa_family) | 1083 | if ((AF_UNIX == sa->sa_family) |
1071 | #ifdef LINUX | 1084 | #ifdef LINUX |
1072 | /* Permission settings are not required when abstract sockets are used */ | 1085 | /* Permission settings are not required when abstract sockets are used */ |
1073 | && ('\0' != ((const struct sockaddr_un *)sa)->sun_path[0]) | 1086 | && ('\0' != ((const struct sockaddr_un *) sa)->sun_path[0]) |
1074 | #endif | 1087 | #endif |
1075 | ) | 1088 | ) |
1076 | { | 1089 | { |
1077 | match_uid = | 1090 | match_uid = |
1078 | GNUNET_CONFIGURATION_get_value_yesno(cfg, sl->name, "UNIX_MATCH_UID"); | 1091 | GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name, "UNIX_MATCH_UID"); |
1079 | match_gid = | 1092 | match_gid = |
1080 | GNUNET_CONFIGURATION_get_value_yesno(cfg, sl->name, "UNIX_MATCH_GID"); | 1093 | GNUNET_CONFIGURATION_get_value_yesno (cfg, sl->name, "UNIX_MATCH_GID"); |
1081 | GNUNET_DISK_fix_permissions(((const struct sockaddr_un *)sa)->sun_path, | 1094 | GNUNET_DISK_fix_permissions (((const struct sockaddr_un *) sa)->sun_path, |
1082 | match_uid, | 1095 | match_uid, |
1083 | match_gid); | 1096 | match_gid); |
1084 | } | 1097 | } |
1085 | if (GNUNET_OK != GNUNET_NETWORK_socket_listen(sock, 5)) | 1098 | if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5)) |
1086 | { | 1099 | { |
1087 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "listen"); | 1100 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "listen"); |
1088 | GNUNET_break(GNUNET_OK == GNUNET_NETWORK_socket_close(sock)); | 1101 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); |
1089 | GNUNET_free(sa); | 1102 | GNUNET_free (sa); |
1090 | return; | 1103 | return; |
1091 | } | 1104 | } |
1092 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | 1105 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1093 | _("ARM now monitors connections to service `%s' at `%s'\n"), | 1106 | _ ("ARM now monitors connections to service `%s' at `%s'\n"), |
1094 | sl->name, | 1107 | sl->name, |
1095 | GNUNET_a2s(sa, addr_len)); | 1108 | GNUNET_a2s (sa, addr_len)); |
1096 | sli = GNUNET_new(struct ServiceListeningInfo); | 1109 | sli = GNUNET_new (struct ServiceListeningInfo); |
1097 | sli->service_addr = sa; | 1110 | sli->service_addr = sa; |
1098 | sli->service_addr_len = addr_len; | 1111 | sli->service_addr_len = addr_len; |
1099 | sli->listen_socket = sock; | 1112 | sli->listen_socket = sock; |
1100 | sli->sl = sl; | 1113 | sli->sl = sl; |
1101 | sli->accept_task = | 1114 | sli->accept_task = |
1102 | GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, | 1115 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
1103 | sock, | 1116 | sock, |
1104 | &accept_connection, | 1117 | &accept_connection, |
1105 | sli); | 1118 | sli); |
1106 | GNUNET_CONTAINER_DLL_insert(sl->listen_head, sl->listen_tail, sli); | 1119 | GNUNET_CONTAINER_DLL_insert (sl->listen_head, sl->listen_tail, sli); |
1107 | } | 1120 | } |
1108 | 1121 | ||
1109 | 1122 | ||
@@ -1114,15 +1127,15 @@ create_listen_socket(struct sockaddr *sa, | |||
1114 | * @param sl entry to free | 1127 | * @param sl entry to free |
1115 | */ | 1128 | */ |
1116 | static void | 1129 | static void |
1117 | free_service(struct ServiceList *sl) | 1130 | free_service (struct ServiceList *sl) |
1118 | { | 1131 | { |
1119 | GNUNET_assert(GNUNET_YES == in_shutdown); | 1132 | GNUNET_assert (GNUNET_YES == in_shutdown); |
1120 | GNUNET_CONTAINER_DLL_remove(running_head, running_tail, sl); | 1133 | GNUNET_CONTAINER_DLL_remove (running_head, running_tail, sl); |
1121 | GNUNET_assert(NULL == sl->listen_head); | 1134 | GNUNET_assert (NULL == sl->listen_head); |
1122 | GNUNET_free_non_null(sl->config); | 1135 | GNUNET_free_non_null (sl->config); |
1123 | GNUNET_free_non_null(sl->binary); | 1136 | GNUNET_free_non_null (sl->binary); |
1124 | GNUNET_free(sl->name); | 1137 | GNUNET_free (sl->name); |
1125 | GNUNET_free(sl); | 1138 | GNUNET_free (sl); |
1126 | } | 1139 | } |
1127 | 1140 | ||
1128 | 1141 | ||
@@ -1135,10 +1148,10 @@ free_service(struct ServiceList *sl) | |||
1135 | * #GNUNET_SYSERR to close it (signal serious error) | 1148 | * #GNUNET_SYSERR to close it (signal serious error) |
1136 | */ | 1149 | */ |
1137 | static int | 1150 | static int |
1138 | check_start(void *cls, const struct GNUNET_ARM_Message *amsg) | 1151 | check_start (void *cls, const struct GNUNET_ARM_Message *amsg) |
1139 | { | 1152 | { |
1140 | (void)cls; | 1153 | (void) cls; |
1141 | GNUNET_MQ_check_zero_termination(amsg); | 1154 | GNUNET_MQ_check_zero_termination (amsg); |
1142 | return GNUNET_OK; | 1155 | return GNUNET_OK; |
1143 | } | 1156 | } |
1144 | 1157 | ||
@@ -1150,43 +1163,43 @@ check_start(void *cls, const struct GNUNET_ARM_Message *amsg) | |||
1150 | * @param amsg the actual message | 1163 | * @param amsg the actual message |
1151 | */ | 1164 | */ |
1152 | static void | 1165 | static void |
1153 | handle_start(void *cls, const struct GNUNET_ARM_Message *amsg) | 1166 | handle_start (void *cls, const struct GNUNET_ARM_Message *amsg) |
1154 | { | 1167 | { |
1155 | struct GNUNET_SERVICE_Client *client = cls; | 1168 | struct GNUNET_SERVICE_Client *client = cls; |
1156 | const char *servicename; | 1169 | const char *servicename; |
1157 | struct ServiceList *sl; | 1170 | struct ServiceList *sl; |
1158 | uint64_t request_id; | 1171 | uint64_t request_id; |
1159 | 1172 | ||
1160 | request_id = GNUNET_ntohll(amsg->request_id); | 1173 | request_id = GNUNET_ntohll (amsg->request_id); |
1161 | servicename = (const char *)&amsg[1]; | 1174 | servicename = (const char *) &amsg[1]; |
1162 | GNUNET_SERVICE_client_continue(client); | 1175 | GNUNET_SERVICE_client_continue (client); |
1163 | if (GNUNET_YES == in_shutdown) | 1176 | if (GNUNET_YES == in_shutdown) |
1164 | { | 1177 | { |
1165 | signal_result(client, | 1178 | signal_result (client, |
1166 | servicename, | 1179 | servicename, |
1167 | request_id, | 1180 | request_id, |
1168 | GNUNET_ARM_RESULT_IN_SHUTDOWN); | 1181 | GNUNET_ARM_RESULT_IN_SHUTDOWN); |
1169 | return; | 1182 | return; |
1170 | } | 1183 | } |
1171 | sl = find_service(servicename); | 1184 | sl = find_service (servicename); |
1172 | if (NULL == sl) | 1185 | if (NULL == sl) |
1173 | { | 1186 | { |
1174 | signal_result(client, | 1187 | signal_result (client, |
1175 | servicename, | 1188 | servicename, |
1176 | request_id, | 1189 | request_id, |
1177 | GNUNET_ARM_RESULT_IS_NOT_KNOWN); | 1190 | GNUNET_ARM_RESULT_IS_NOT_KNOWN); |
1178 | return; | 1191 | return; |
1179 | } | 1192 | } |
1180 | sl->force_start = GNUNET_YES; | 1193 | sl->force_start = GNUNET_YES; |
1181 | if (NULL != sl->proc) | 1194 | if (NULL != sl->proc) |
1182 | { | 1195 | { |
1183 | signal_result(client, | 1196 | signal_result (client, |
1184 | servicename, | 1197 | servicename, |
1185 | request_id, | 1198 | request_id, |
1186 | GNUNET_ARM_RESULT_IS_STARTED_ALREADY); | 1199 | GNUNET_ARM_RESULT_IS_STARTED_ALREADY); |
1187 | return; | 1200 | return; |
1188 | } | 1201 | } |
1189 | start_process(sl, client, request_id); | 1202 | start_process (sl, client, request_id); |
1190 | } | 1203 | } |
1191 | 1204 | ||
1192 | 1205 | ||
@@ -1196,11 +1209,11 @@ handle_start(void *cls, const struct GNUNET_ARM_Message *amsg) | |||
1196 | * @param cls closure (refers to service) | 1209 | * @param cls closure (refers to service) |
1197 | */ | 1210 | */ |
1198 | static void | 1211 | static void |
1199 | trigger_shutdown(void *cls) | 1212 | trigger_shutdown (void *cls) |
1200 | { | 1213 | { |
1201 | (void)cls; | 1214 | (void) cls; |
1202 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Triggering shutdown\n"); | 1215 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Triggering shutdown\n"); |
1203 | GNUNET_SCHEDULER_shutdown(); | 1216 | GNUNET_SCHEDULER_shutdown (); |
1204 | } | 1217 | } |
1205 | 1218 | ||
1206 | 1219 | ||
@@ -1213,10 +1226,10 @@ trigger_shutdown(void *cls) | |||
1213 | * #GNUNET_SYSERR to close it (signal serious error) | 1226 | * #GNUNET_SYSERR to close it (signal serious error) |
1214 | */ | 1227 | */ |
1215 | static int | 1228 | static int |
1216 | check_stop(void *cls, const struct GNUNET_ARM_Message *amsg) | 1229 | check_stop (void *cls, const struct GNUNET_ARM_Message *amsg) |
1217 | { | 1230 | { |
1218 | (void)cls; | 1231 | (void) cls; |
1219 | GNUNET_MQ_check_zero_termination(amsg); | 1232 | GNUNET_MQ_check_zero_termination (amsg); |
1220 | return GNUNET_OK; | 1233 | return GNUNET_OK; |
1221 | } | 1234 | } |
1222 | 1235 | ||
@@ -1228,128 +1241,184 @@ check_stop(void *cls, const struct GNUNET_ARM_Message *amsg) | |||
1228 | * @param amsg the actual message | 1241 | * @param amsg the actual message |
1229 | */ | 1242 | */ |
1230 | static void | 1243 | static void |
1231 | handle_stop(void *cls, const struct GNUNET_ARM_Message *amsg) | 1244 | handle_stop (void *cls, const struct GNUNET_ARM_Message *amsg) |
1232 | { | 1245 | { |
1233 | struct GNUNET_SERVICE_Client *client = cls; | 1246 | struct GNUNET_SERVICE_Client *client = cls; |
1234 | struct ServiceList *sl; | 1247 | struct ServiceList *sl; |
1235 | const char *servicename; | 1248 | const char *servicename; |
1236 | uint64_t request_id; | 1249 | uint64_t request_id; |
1237 | 1250 | ||
1238 | request_id = GNUNET_ntohll(amsg->request_id); | 1251 | request_id = GNUNET_ntohll (amsg->request_id); |
1239 | servicename = (const char *)&amsg[1]; | 1252 | servicename = (const char *) &amsg[1]; |
1240 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | 1253 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1241 | _("Preparing to stop `%s'\n"), | 1254 | _ ("Preparing to stop `%s'\n"), |
1242 | servicename); | 1255 | servicename); |
1243 | GNUNET_SERVICE_client_continue(client); | 1256 | GNUNET_SERVICE_client_continue (client); |
1244 | if (0 == strcasecmp(servicename, "arm")) | 1257 | if (0 == strcasecmp (servicename, "arm")) |
1245 | { | 1258 | { |
1246 | broadcast_status(servicename, GNUNET_ARM_SERVICE_STOPPING, NULL); | 1259 | broadcast_status (servicename, GNUNET_ARM_SERVICE_STOPPING, NULL); |
1247 | signal_result(client, servicename, request_id, GNUNET_ARM_RESULT_STOPPING); | 1260 | signal_result (client, servicename, request_id, GNUNET_ARM_RESULT_STOPPING); |
1248 | GNUNET_SERVICE_client_persist(client); | 1261 | GNUNET_SERVICE_client_persist (client); |
1249 | GNUNET_SCHEDULER_add_now(&trigger_shutdown, NULL); | 1262 | GNUNET_SCHEDULER_add_now (&trigger_shutdown, NULL); |
1250 | return; | 1263 | return; |
1251 | } | 1264 | } |
1252 | sl = find_service(servicename); | 1265 | sl = find_service (servicename); |
1253 | if (NULL == sl) | 1266 | if (NULL == sl) |
1254 | { | 1267 | { |
1255 | signal_result(client, | 1268 | signal_result (client, |
1256 | servicename, | 1269 | servicename, |
1257 | request_id, | 1270 | request_id, |
1258 | GNUNET_ARM_RESULT_IS_NOT_KNOWN); | 1271 | GNUNET_ARM_RESULT_IS_NOT_KNOWN); |
1259 | return; | 1272 | return; |
1260 | } | 1273 | } |
1261 | sl->force_start = GNUNET_NO; | 1274 | sl->force_start = GNUNET_NO; |
1262 | if (GNUNET_YES == in_shutdown) | 1275 | if (GNUNET_YES == in_shutdown) |
1263 | { | 1276 | { |
1264 | /* shutdown in progress */ | 1277 | /* shutdown in progress */ |
1265 | signal_result(client, | 1278 | signal_result (client, |
1266 | servicename, | 1279 | servicename, |
1267 | request_id, | 1280 | request_id, |
1268 | GNUNET_ARM_RESULT_IN_SHUTDOWN); | 1281 | GNUNET_ARM_RESULT_IN_SHUTDOWN); |
1269 | return; | 1282 | return; |
1270 | } | 1283 | } |
1271 | if (NULL != sl->killing_client) | 1284 | if (NULL != sl->killing_client) |
1272 | { | 1285 | { |
1273 | /* killing already in progress */ | 1286 | /* killing already in progress */ |
1274 | signal_result(client, | 1287 | signal_result (client, |
1275 | servicename, | 1288 | servicename, |
1276 | request_id, | 1289 | request_id, |
1277 | GNUNET_ARM_RESULT_IS_STOPPING_ALREADY); | 1290 | GNUNET_ARM_RESULT_IS_STOPPING_ALREADY); |
1278 | return; | 1291 | return; |
1279 | } | 1292 | } |
1280 | if (NULL == sl->proc) | 1293 | if (NULL == sl->proc) |
1281 | { | 1294 | { |
1282 | /* process is down */ | 1295 | /* process is down */ |
1283 | signal_result(client, | 1296 | signal_result (client, |
1284 | servicename, | 1297 | servicename, |
1285 | request_id, | 1298 | request_id, |
1286 | GNUNET_ARM_RESULT_IS_STOPPED_ALREADY); | 1299 | GNUNET_ARM_RESULT_IS_STOPPED_ALREADY); |
1287 | return; | 1300 | return; |
1288 | } | 1301 | } |
1289 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 1302 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1290 | "Sending kill signal to service `%s', waiting for process to die.\n", | 1303 | "Sending kill signal to service `%s', waiting for process to die.\n", |
1291 | servicename); | 1304 | servicename); |
1292 | broadcast_status(servicename, GNUNET_ARM_SERVICE_STOPPING, NULL); | 1305 | broadcast_status (servicename, GNUNET_ARM_SERVICE_STOPPING, NULL); |
1293 | /* no signal_start - only when it's STOPPED */ | 1306 | /* no signal_start - only when it's STOPPED */ |
1294 | sl->killed_at = GNUNET_TIME_absolute_get(); | 1307 | sl->killed_at = GNUNET_TIME_absolute_get (); |
1295 | if (0 != GNUNET_OS_process_kill(sl->proc, GNUNET_TERM_SIG)) | 1308 | if (0 != GNUNET_OS_process_kill (sl->proc, GNUNET_TERM_SIG)) |
1296 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "kill"); | 1309 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); |
1297 | sl->killing_client = client; | 1310 | sl->killing_client = client; |
1298 | sl->killing_client_request_id = request_id; | 1311 | sl->killing_client_request_id = request_id; |
1299 | } | 1312 | } |
1300 | 1313 | ||
1301 | 1314 | ||
1302 | /** | 1315 | /** |
1316 | * Write a string to a string pool. | ||
1317 | * | ||
1318 | * @param pool_start pointer to the start of the string pool | ||
1319 | * @param pool_size size of the string pool | ||
1320 | * @param[in,out] pool_pos current position index in the string pool, | ||
1321 | * will be updated | ||
1322 | * @param str string to write to the string pool | ||
1323 | * @returns GNUNET_OK if the string fits into the pool, | ||
1324 | * GNUNET_SYSERR otherwise | ||
1325 | */ | ||
1326 | static int | ||
1327 | pool_write (char *pool_start, size_t pool_size, size_t *pool_pos, char *str) | ||
1328 | { | ||
1329 | size_t next_pos = (*pool_pos) + strlen (str) + 1; | ||
1330 | |||
1331 | if (next_pos > pool_size) | ||
1332 | return GNUNET_SYSERR; | ||
1333 | memcpy (pool_start + *pool_pos, str, strlen (str) + 1); | ||
1334 | *pool_pos = next_pos; | ||
1335 | return GNUNET_OK; | ||
1336 | } | ||
1337 | |||
1338 | /** | ||
1303 | * Handle LIST-message. | 1339 | * Handle LIST-message. |
1304 | * | 1340 | * |
1305 | * @param cls identification of the client | 1341 | * @param cls identification of the client |
1306 | * @param message the actual message | 1342 | * @param message the actual message |
1307 | */ | 1343 | */ |
1308 | static void | 1344 | static void |
1309 | handle_list(void *cls, const struct GNUNET_ARM_Message *request) | 1345 | handle_list (void *cls, const struct GNUNET_ARM_Message *request) |
1310 | { | 1346 | { |
1311 | struct GNUNET_SERVICE_Client *client = cls; | 1347 | struct GNUNET_SERVICE_Client *client = cls; |
1312 | struct GNUNET_MQ_Envelope *env; | 1348 | struct GNUNET_MQ_Envelope *env; |
1313 | struct GNUNET_ARM_ListResultMessage *msg; | 1349 | struct GNUNET_ARM_ListResultMessage *msg; |
1314 | size_t string_list_size; | 1350 | size_t extra_size; |
1315 | struct ServiceList *sl; | 1351 | struct ServiceList *sl; |
1316 | uint16_t count; | 1352 | uint16_t count; |
1317 | char *pos; | 1353 | size_t pool_size; |
1354 | size_t pool_pos; | ||
1355 | char *pool_start; | ||
1356 | struct GNUNET_ARM_ServiceInfoMessage *ssm; | ||
1318 | 1357 | ||
1319 | GNUNET_break(0 == ntohl(request->reserved)); | 1358 | GNUNET_break_op (0 == ntohl (request->reserved)); |
1320 | count = 0; | 1359 | count = 0; |
1321 | string_list_size = 0; | 1360 | pool_size = 0; |
1322 | 1361 | ||
1323 | /* first count the running processes get their name's size */ | 1362 | /* Do one pass over the list to compute the number of services |
1363 | * and the string pool size */ | ||
1324 | for (sl = running_head; NULL != sl; sl = sl->next) | 1364 | for (sl = running_head; NULL != sl; sl = sl->next) |
1325 | { | 1365 | { |
1326 | if (NULL != sl->proc) | 1366 | pool_size += strlen (sl->name) + 1; |
1327 | { | 1367 | pool_size += strlen (sl->binary) + 1; |
1328 | string_list_size += strlen(sl->name); | 1368 | count++; |
1329 | string_list_size += strlen(sl->binary); | 1369 | } |
1330 | string_list_size += 4; | ||
1331 | count++; | ||
1332 | } | ||
1333 | } | ||
1334 | 1370 | ||
1335 | env = GNUNET_MQ_msg_extra(msg, | 1371 | extra_size = pool_size + (count * sizeof (struct |
1336 | string_list_size, | 1372 | GNUNET_ARM_ServiceInfoMessage)); |
1337 | GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT); | 1373 | env = GNUNET_MQ_msg_extra (msg, |
1374 | extra_size, | ||
1375 | GNUNET_MESSAGE_TYPE_ARM_LIST_RESULT); | ||
1338 | msg->arm_msg.request_id = request->request_id; | 1376 | msg->arm_msg.request_id = request->request_id; |
1339 | msg->count = htons(count); | 1377 | msg->count = htons (count); |
1378 | |||
1379 | ssm = (struct GNUNET_ARM_ServiceInfoMessage *) &msg[1]; | ||
1380 | pool_start = (char *) (ssm + count); | ||
1381 | pool_pos = 0; | ||
1340 | 1382 | ||
1341 | pos = (char *)&msg[1]; | ||
1342 | for (sl = running_head; NULL != sl; sl = sl->next) | 1383 | for (sl = running_head; NULL != sl; sl = sl->next) |
1384 | { | ||
1385 | ssm->name_index = htons ((uint16_t) pool_pos); | ||
1386 | GNUNET_assert (GNUNET_OK == pool_write (pool_start, pool_size, &pool_pos, | ||
1387 | sl->name)); | ||
1388 | ssm->binary_index = htons ((uint16_t) pool_pos); | ||
1389 | GNUNET_assert (GNUNET_OK == pool_write (pool_start, pool_size, &pool_pos, | ||
1390 | sl->binary)); | ||
1391 | if (NULL == sl->proc) | ||
1343 | { | 1392 | { |
1344 | if (NULL != sl->proc) | 1393 | if (0 == sl->last_started_at.abs_value_us) |
1345 | { | 1394 | { |
1346 | size_t s = strlen(sl->name) + strlen(sl->binary) + 4; | 1395 | /* Process never started */ |
1347 | GNUNET_snprintf(pos, s, "%s (%s)", sl->name, sl->binary); | 1396 | ssm->status = htonl (GNUNET_ARM_SERVICE_STATUS_STOPPED); |
1348 | pos += s; | 1397 | } |
1349 | } | 1398 | else if (0 == sl->last_exit_status) |
1399 | { | ||
1400 | ssm->status = htonl (GNUNET_ARM_SERVICE_STATUS_FINISHED); | ||
1401 | } | ||
1402 | else | ||
1403 | { | ||
1404 | ssm->status = htonl (GNUNET_ARM_SERVICE_STATUS_FAILED); | ||
1405 | ssm->last_exit_status = htons (sl->last_exit_status); | ||
1406 | } | ||
1407 | } | ||
1408 | else if ((NULL != sl->killing_client) || (GNUNET_YES == in_shutdown)) | ||
1409 | { | ||
1410 | ssm->status = htonl (GNUNET_ARM_SERVICE_STATUS_STOPPING); | ||
1411 | } | ||
1412 | else | ||
1413 | { | ||
1414 | ssm->status = htonl (GNUNET_ARM_SERVICE_STATUS_STARTED); | ||
1350 | } | 1415 | } |
1351 | GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(client), env); | 1416 | ssm->last_started_at = GNUNET_TIME_absolute_hton (sl->last_started_at); |
1352 | GNUNET_SERVICE_client_continue(client); | 1417 | ssm->restart_at = GNUNET_TIME_absolute_hton (sl->restart_at); |
1418 | ssm++; | ||
1419 | } | ||
1420 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env); | ||
1421 | GNUNET_SERVICE_client_continue (client); | ||
1353 | } | 1422 | } |
1354 | 1423 | ||
1355 | 1424 | ||
@@ -1360,16 +1429,16 @@ handle_list(void *cls, const struct GNUNET_ARM_Message *request) | |||
1360 | * @param message the actual message | 1429 | * @param message the actual message |
1361 | */ | 1430 | */ |
1362 | static void | 1431 | static void |
1363 | handle_test(void *cls, const struct GNUNET_MessageHeader *message) | 1432 | handle_test (void *cls, const struct GNUNET_MessageHeader *message) |
1364 | { | 1433 | { |
1365 | struct GNUNET_SERVICE_Client *client = cls; | 1434 | struct GNUNET_SERVICE_Client *client = cls; |
1366 | struct GNUNET_MQ_Envelope *env; | 1435 | struct GNUNET_MQ_Envelope *env; |
1367 | struct GNUNET_MessageHeader *msg; | 1436 | struct GNUNET_MessageHeader *msg; |
1368 | 1437 | ||
1369 | (void)message; | 1438 | (void) message; |
1370 | env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_ARM_TEST); | 1439 | env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_ARM_TEST); |
1371 | GNUNET_MQ_send(GNUNET_SERVICE_client_get_mq(client), env); | 1440 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env); |
1372 | GNUNET_SERVICE_client_continue(client); | 1441 | GNUNET_SERVICE_client_continue (client); |
1373 | } | 1442 | } |
1374 | 1443 | ||
1375 | 1444 | ||
@@ -1378,24 +1447,24 @@ handle_test(void *cls, const struct GNUNET_MessageHeader *message) | |||
1378 | * tasks, signal handler and the server. | 1447 | * tasks, signal handler and the server. |
1379 | */ | 1448 | */ |
1380 | static void | 1449 | static void |
1381 | do_shutdown() | 1450 | do_shutdown () |
1382 | { | 1451 | { |
1383 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Last shutdown phase\n"); | 1452 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Last shutdown phase\n"); |
1384 | if (NULL != notifier) | 1453 | if (NULL != notifier) |
1385 | { | 1454 | { |
1386 | GNUNET_notification_context_destroy(notifier); | 1455 | GNUNET_notification_context_destroy (notifier); |
1387 | notifier = NULL; | 1456 | notifier = NULL; |
1388 | } | 1457 | } |
1389 | if (NULL != service) | 1458 | if (NULL != service) |
1390 | { | 1459 | { |
1391 | GNUNET_SERVICE_shutdown(service); | 1460 | GNUNET_SERVICE_shutdown (service); |
1392 | service = NULL; | 1461 | service = NULL; |
1393 | } | 1462 | } |
1394 | if (NULL != child_death_task) | 1463 | if (NULL != child_death_task) |
1395 | { | 1464 | { |
1396 | GNUNET_SCHEDULER_cancel(child_death_task); | 1465 | GNUNET_SCHEDULER_cancel (child_death_task); |
1397 | child_death_task = NULL; | 1466 | child_death_task = NULL; |
1398 | } | 1467 | } |
1399 | } | 1468 | } |
1400 | 1469 | ||
1401 | 1470 | ||
@@ -1406,13 +1475,13 @@ do_shutdown() | |||
1406 | * @return number of active services found | 1475 | * @return number of active services found |
1407 | */ | 1476 | */ |
1408 | static unsigned int | 1477 | static unsigned int |
1409 | list_count(struct ServiceList *running_head) | 1478 | list_count (struct ServiceList *running_head) |
1410 | { | 1479 | { |
1411 | struct ServiceList *i; | 1480 | struct ServiceList *i; |
1412 | unsigned int res; | 1481 | unsigned int res; |
1413 | 1482 | ||
1414 | for (res = 0, i = running_head; NULL != i; i = i->next, res++) | 1483 | for (res = 0, i = running_head; NULL != i; i = i->next, res++) |
1415 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s\n", i->name); | 1484 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s\n", i->name); |
1416 | return res; | 1485 | return res; |
1417 | } | 1486 | } |
1418 | 1487 | ||
@@ -1423,61 +1492,61 @@ list_count(struct ServiceList *running_head) | |||
1423 | * @param cls closure, NULL if we need to self-restart | 1492 | * @param cls closure, NULL if we need to self-restart |
1424 | */ | 1493 | */ |
1425 | static void | 1494 | static void |
1426 | shutdown_task(void *cls) | 1495 | shutdown_task (void *cls) |
1427 | { | 1496 | { |
1428 | struct ServiceList *pos; | 1497 | struct ServiceList *pos; |
1429 | struct ServiceList *nxt; | 1498 | struct ServiceList *nxt; |
1430 | struct ServiceListeningInfo *sli; | 1499 | struct ServiceListeningInfo *sli; |
1431 | 1500 | ||
1432 | (void)cls; | 1501 | (void) cls; |
1433 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "First shutdown phase\n"); | 1502 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "First shutdown phase\n"); |
1434 | if (NULL != child_restart_task) | 1503 | if (NULL != child_restart_task) |
1435 | { | 1504 | { |
1436 | GNUNET_SCHEDULER_cancel(child_restart_task); | 1505 | GNUNET_SCHEDULER_cancel (child_restart_task); |
1437 | child_restart_task = NULL; | 1506 | child_restart_task = NULL; |
1438 | } | 1507 | } |
1439 | in_shutdown = GNUNET_YES; | 1508 | in_shutdown = GNUNET_YES; |
1440 | /* first, stop listening */ | 1509 | /* first, stop listening */ |
1441 | for (pos = running_head; NULL != pos; pos = pos->next) | 1510 | for (pos = running_head; NULL != pos; pos = pos->next) |
1511 | { | ||
1512 | while (NULL != (sli = pos->listen_head)) | ||
1442 | { | 1513 | { |
1443 | while (NULL != (sli = pos->listen_head)) | 1514 | GNUNET_CONTAINER_DLL_remove (pos->listen_head, pos->listen_tail, sli); |
1444 | { | 1515 | if (NULL != sli->accept_task) |
1445 | GNUNET_CONTAINER_DLL_remove(pos->listen_head, pos->listen_tail, sli); | 1516 | { |
1446 | if (NULL != sli->accept_task) | 1517 | GNUNET_SCHEDULER_cancel (sli->accept_task); |
1447 | { | 1518 | sli->accept_task = NULL; |
1448 | GNUNET_SCHEDULER_cancel(sli->accept_task); | 1519 | } |
1449 | sli->accept_task = NULL; | 1520 | GNUNET_break (GNUNET_OK == |
1450 | } | 1521 | GNUNET_NETWORK_socket_close (sli->listen_socket)); |
1451 | GNUNET_break(GNUNET_OK == | 1522 | GNUNET_free (sli->service_addr); |
1452 | GNUNET_NETWORK_socket_close(sli->listen_socket)); | 1523 | GNUNET_free (sli); |
1453 | GNUNET_free(sli->service_addr); | ||
1454 | GNUNET_free(sli); | ||
1455 | } | ||
1456 | } | 1524 | } |
1525 | } | ||
1457 | /* then, shutdown all existing service processes */ | 1526 | /* then, shutdown all existing service processes */ |
1458 | nxt = running_head; | 1527 | nxt = running_head; |
1459 | while (NULL != (pos = nxt)) | 1528 | while (NULL != (pos = nxt)) |
1529 | { | ||
1530 | nxt = pos->next; | ||
1531 | if (NULL != pos->proc) | ||
1460 | { | 1532 | { |
1461 | nxt = pos->next; | 1533 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stopping service `%s'\n", pos->name); |
1462 | if (NULL != pos->proc) | 1534 | pos->killed_at = GNUNET_TIME_absolute_get (); |
1463 | { | 1535 | if (0 != GNUNET_OS_process_kill (pos->proc, GNUNET_TERM_SIG)) |
1464 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Stopping service `%s'\n", pos->name); | 1536 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); |
1465 | pos->killed_at = GNUNET_TIME_absolute_get(); | ||
1466 | if (0 != GNUNET_OS_process_kill(pos->proc, GNUNET_TERM_SIG)) | ||
1467 | GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "kill"); | ||
1468 | } | ||
1469 | else | ||
1470 | { | ||
1471 | free_service(pos); | ||
1472 | } | ||
1473 | } | 1537 | } |
1538 | else | ||
1539 | { | ||
1540 | free_service (pos); | ||
1541 | } | ||
1542 | } | ||
1474 | /* finally, should all service processes be already gone, terminate for real */ | 1543 | /* finally, should all service processes be already gone, terminate for real */ |
1475 | if (NULL == running_head) | 1544 | if (NULL == running_head) |
1476 | do_shutdown(); | 1545 | do_shutdown (); |
1477 | else | 1546 | else |
1478 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 1547 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1479 | "Delaying shutdown, have %u childs still running\n", | 1548 | "Delaying shutdown, have %u childs still running\n", |
1480 | list_count(running_head)); | 1549 | list_count (running_head)); |
1481 | } | 1550 | } |
1482 | 1551 | ||
1483 | 1552 | ||
@@ -1487,73 +1556,73 @@ shutdown_task(void *cls) | |||
1487 | * @param cls closure, always NULL | 1556 | * @param cls closure, always NULL |
1488 | */ | 1557 | */ |
1489 | static void | 1558 | static void |
1490 | delayed_restart_task(void *cls) | 1559 | delayed_restart_task (void *cls) |
1491 | 1560 | ||
1492 | { | 1561 | { |
1493 | struct ServiceList *sl; | 1562 | struct ServiceList *sl; |
1494 | struct GNUNET_TIME_Relative lowestRestartDelay; | 1563 | struct GNUNET_TIME_Relative lowestRestartDelay; |
1495 | struct ServiceListeningInfo *sli; | 1564 | struct ServiceListeningInfo *sli; |
1496 | 1565 | ||
1497 | (void)cls; | 1566 | (void) cls; |
1498 | child_restart_task = NULL; | 1567 | child_restart_task = NULL; |
1499 | GNUNET_assert(GNUNET_NO == in_shutdown); | 1568 | GNUNET_assert (GNUNET_NO == in_shutdown); |
1500 | lowestRestartDelay = GNUNET_TIME_UNIT_FOREVER_REL; | 1569 | lowestRestartDelay = GNUNET_TIME_UNIT_FOREVER_REL; |
1501 | 1570 | ||
1502 | /* check for services that need to be restarted due to | 1571 | /* check for services that need to be restarted due to |
1503 | * configuration changes or because the last restart failed */ | 1572 | * configuration changes or because the last restart failed */ |
1504 | for (sl = running_head; NULL != sl; sl = sl->next) | 1573 | for (sl = running_head; NULL != sl; sl = sl->next) |
1574 | { | ||
1575 | if (NULL != sl->proc) | ||
1576 | continue; | ||
1577 | /* service is currently not running */ | ||
1578 | if (0 == GNUNET_TIME_absolute_get_remaining (sl->restart_at).rel_value_us) | ||
1505 | { | 1579 | { |
1506 | if (NULL != sl->proc) | 1580 | /* restart is now allowed */ |
1507 | continue; | 1581 | if (sl->force_start) |
1508 | /* service is currently not running */ | 1582 | { |
1509 | if (0 == GNUNET_TIME_absolute_get_remaining(sl->restart_at).rel_value_us) | 1583 | /* process should run by default, start immediately */ |
1510 | { | 1584 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1511 | /* restart is now allowed */ | 1585 | _ ("Restarting service `%s'.\n"), |
1512 | if (sl->force_start) | 1586 | sl->name); |
1513 | { | 1587 | start_process (sl, NULL, 0); |
1514 | /* process should run by default, start immediately */ | 1588 | } |
1515 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | ||
1516 | _("Restarting service `%s'.\n"), | ||
1517 | sl->name); | ||
1518 | start_process(sl, NULL, 0); | ||
1519 | } | ||
1520 | else | ||
1521 | { | ||
1522 | /* process is run on-demand, ensure it is re-started if there is demand */ | ||
1523 | for (sli = sl->listen_head; NULL != sli; sli = sli->next) | ||
1524 | if (NULL == sli->accept_task) | ||
1525 | { | ||
1526 | /* accept was actually paused, so start it again */ | ||
1527 | sli->accept_task = | ||
1528 | GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, | ||
1529 | sli->listen_socket, | ||
1530 | &accept_connection, | ||
1531 | sli); | ||
1532 | } | ||
1533 | } | ||
1534 | } | ||
1535 | else | 1589 | else |
1536 | { | 1590 | { |
1537 | /* update calculation for earliest time to reactivate a service */ | 1591 | /* process is run on-demand, ensure it is re-started if there is demand */ |
1538 | lowestRestartDelay = | 1592 | for (sli = sl->listen_head; NULL != sli; sli = sli->next) |
1539 | GNUNET_TIME_relative_min(lowestRestartDelay, | 1593 | if (NULL == sli->accept_task) |
1540 | GNUNET_TIME_absolute_get_remaining( | 1594 | { |
1541 | sl->restart_at)); | 1595 | /* accept was actually paused, so start it again */ |
1542 | } | 1596 | sli->accept_task = |
1597 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, | ||
1598 | sli->listen_socket, | ||
1599 | &accept_connection, | ||
1600 | sli); | ||
1601 | } | ||
1602 | } | ||
1603 | } | ||
1604 | else | ||
1605 | { | ||
1606 | /* update calculation for earliest time to reactivate a service */ | ||
1607 | lowestRestartDelay = | ||
1608 | GNUNET_TIME_relative_min (lowestRestartDelay, | ||
1609 | GNUNET_TIME_absolute_get_remaining ( | ||
1610 | sl->restart_at)); | ||
1543 | } | 1611 | } |
1612 | } | ||
1544 | if (lowestRestartDelay.rel_value_us != | 1613 | if (lowestRestartDelay.rel_value_us != |
1545 | GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) | 1614 | GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) |
1546 | { | 1615 | { |
1547 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 1616 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1548 | "Will restart process in %s\n", | 1617 | "Will restart process in %s\n", |
1549 | GNUNET_STRINGS_relative_time_to_string(lowestRestartDelay, | 1618 | GNUNET_STRINGS_relative_time_to_string (lowestRestartDelay, |
1550 | GNUNET_YES)); | 1619 | GNUNET_YES)); |
1551 | child_restart_task = | 1620 | child_restart_task = |
1552 | GNUNET_SCHEDULER_add_delayed_with_priority(lowestRestartDelay, | 1621 | GNUNET_SCHEDULER_add_delayed_with_priority (lowestRestartDelay, |
1553 | GNUNET_SCHEDULER_PRIORITY_IDLE, | 1622 | GNUNET_SCHEDULER_PRIORITY_IDLE, |
1554 | &delayed_restart_task, | 1623 | &delayed_restart_task, |
1555 | NULL); | 1624 | NULL); |
1556 | } | 1625 | } |
1557 | } | 1626 | } |
1558 | 1627 | ||
1559 | 1628 | ||
@@ -1564,7 +1633,7 @@ delayed_restart_task(void *cls) | |||
1564 | * @param cls closure, NULL | 1633 | * @param cls closure, NULL |
1565 | */ | 1634 | */ |
1566 | static void | 1635 | static void |
1567 | maint_child_death(void *cls) | 1636 | maint_child_death (void *cls) |
1568 | { | 1637 | { |
1569 | struct ServiceList *pos; | 1638 | struct ServiceList *pos; |
1570 | struct ServiceList *next; | 1639 | struct ServiceList *next; |
@@ -1577,199 +1646,200 @@ maint_child_death(void *cls) | |||
1577 | unsigned long statusCode; | 1646 | unsigned long statusCode; |
1578 | const struct GNUNET_DISK_FileHandle *pr; | 1647 | const struct GNUNET_DISK_FileHandle *pr; |
1579 | 1648 | ||
1580 | (void)cls; | 1649 | (void) cls; |
1581 | pr = GNUNET_DISK_pipe_handle(sigpipe, GNUNET_DISK_PIPE_END_READ); | 1650 | pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ); |
1582 | child_death_task = NULL; | 1651 | child_death_task = NULL; |
1583 | /* consume the signal */ | 1652 | /* consume the signal */ |
1584 | GNUNET_break(0 < GNUNET_DISK_file_read(pr, &c, sizeof(c))); | 1653 | GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof(c))); |
1585 | 1654 | ||
1586 | /* check for services that died (WAITPID) */ | 1655 | /* check for services that died (WAITPID) */ |
1587 | next = running_head; | 1656 | next = running_head; |
1588 | while (NULL != (pos = next)) | 1657 | while (NULL != (pos = next)) |
1589 | { | 1658 | { |
1590 | next = pos->next; | 1659 | next = pos->next; |
1591 | 1660 | ||
1592 | if (NULL == pos->proc) | 1661 | if (NULL == pos->proc) |
1593 | { | 1662 | { |
1594 | if (GNUNET_YES == in_shutdown) | 1663 | if (GNUNET_YES == in_shutdown) |
1595 | free_service(pos); | 1664 | free_service (pos); |
1596 | continue; | 1665 | continue; |
1597 | } | 1666 | } |
1598 | #if HAVE_WAIT4 | 1667 | #if HAVE_WAIT4 |
1599 | if (NULL != wait_file) | 1668 | if (NULL != wait_file) |
1600 | { | 1669 | { |
1601 | /* need to use 'wait4()' to obtain and log performance data */ | 1670 | /* need to use 'wait4()' to obtain and log performance data */ |
1602 | struct rusage ru; | 1671 | struct rusage ru; |
1603 | int status; | 1672 | int status; |
1604 | pid_t pid; | 1673 | pid_t pid; |
1605 | 1674 | ||
1606 | pid = GNUNET_OS_process_get_pid(pos->proc); | 1675 | pid = GNUNET_OS_process_get_pid (pos->proc); |
1607 | ret = wait4(pid, &status, WNOHANG, &ru); | 1676 | ret = wait4 (pid, &status, WNOHANG, &ru); |
1608 | if (ret <= 0) | 1677 | if (ret <= 0) |
1609 | continue; /* no process done */ | 1678 | continue; /* no process done */ |
1610 | if (WIFEXITED(status)) | 1679 | if (WIFEXITED (status)) |
1611 | { | 1680 | { |
1612 | statusType = GNUNET_OS_PROCESS_EXITED; | 1681 | statusType = GNUNET_OS_PROCESS_EXITED; |
1613 | statusCode = WEXITSTATUS(status); | 1682 | statusCode = WEXITSTATUS (status); |
1614 | } | 1683 | } |
1615 | else if (WIFSIGNALED(status)) | 1684 | else if (WIFSIGNALED (status)) |
1616 | { | 1685 | { |
1617 | statusType = GNUNET_OS_PROCESS_SIGNALED; | 1686 | statusType = GNUNET_OS_PROCESS_SIGNALED; |
1618 | statusCode = WTERMSIG(status); | 1687 | statusCode = WTERMSIG (status); |
1619 | } | 1688 | } |
1620 | else if (WIFSTOPPED(status)) | 1689 | else if (WIFSTOPPED (status)) |
1621 | { | 1690 | { |
1622 | statusType = GNUNET_OS_PROCESS_SIGNALED; | 1691 | statusType = GNUNET_OS_PROCESS_SIGNALED; |
1623 | statusCode = WSTOPSIG(status); | 1692 | statusCode = WSTOPSIG (status); |
1624 | } | 1693 | } |
1625 | #ifdef WIFCONTINUED | 1694 | #ifdef WIFCONTINUED |
1626 | else if (WIFCONTINUED(status)) | 1695 | else if (WIFCONTINUED (status)) |
1627 | { | 1696 | { |
1628 | statusType = GNUNET_OS_PROCESS_RUNNING; | 1697 | statusType = GNUNET_OS_PROCESS_RUNNING; |
1629 | statusCode = 0; | 1698 | statusCode = 0; |
1630 | } | 1699 | } |
1631 | #endif | ||
1632 | else | ||
1633 | { | ||
1634 | statusType = GNUNET_OS_PROCESS_UNKNOWN; | ||
1635 | statusCode = 0; | ||
1636 | } | ||
1637 | if ((GNUNET_OS_PROCESS_EXITED == statusType) || | ||
1638 | (GNUNET_OS_PROCESS_SIGNALED == statusType)) | ||
1639 | { | ||
1640 | double utime = ru.ru_utime.tv_sec + (ru.ru_utime.tv_usec / 10e6); | ||
1641 | double stime = ru.ru_stime.tv_sec + (ru.ru_stime.tv_usec / 10e6); | ||
1642 | fprintf(wait_file, | ||
1643 | "%s(%u) %.3f %.3f %llu %llu %llu %llu %llu\n", | ||
1644 | pos->binary, | ||
1645 | (unsigned int)pid, | ||
1646 | utime, | ||
1647 | stime, | ||
1648 | (unsigned long long)ru.ru_maxrss, | ||
1649 | (unsigned long long)ru.ru_inblock, | ||
1650 | (unsigned long long)ru.ru_oublock, | ||
1651 | (unsigned long long)ru.ru_nvcsw, | ||
1652 | (unsigned long long)ru.ru_nivcsw); | ||
1653 | } | ||
1654 | } | ||
1655 | else /* continue with JUST this "if" as "else" (intentionally no brackets!) */ | ||
1656 | #endif | 1700 | #endif |
1657 | if ((GNUNET_SYSERR == (ret = GNUNET_OS_process_status(pos->proc, | ||
1658 | &statusType, | ||
1659 | &statusCode))) || | ||
1660 | (ret == GNUNET_NO) || (statusType == GNUNET_OS_PROCESS_STOPPED) || | ||
1661 | (statusType == GNUNET_OS_PROCESS_UNKNOWN) || | ||
1662 | (statusType == GNUNET_OS_PROCESS_RUNNING)) | ||
1663 | continue; | ||
1664 | |||
1665 | if (statusType == GNUNET_OS_PROCESS_EXITED) | ||
1666 | { | ||
1667 | statstr = _(/* process termination method */ "exit"); | ||
1668 | statcode = statusCode; | ||
1669 | } | ||
1670 | else if (statusType == GNUNET_OS_PROCESS_SIGNALED) | ||
1671 | { | ||
1672 | statstr = _(/* process termination method */ "signal"); | ||
1673 | statcode = statusCode; | ||
1674 | } | ||
1675 | else | 1701 | else |
1676 | { | 1702 | { |
1677 | statstr = _(/* process termination method */ "unknown"); | 1703 | statusType = GNUNET_OS_PROCESS_UNKNOWN; |
1678 | statcode = 0; | 1704 | statusCode = 0; |
1679 | } | 1705 | } |
1680 | if (0 != pos->killed_at.abs_value_us) | 1706 | if ((GNUNET_OS_PROCESS_EXITED == statusType) || |
1681 | { | 1707 | (GNUNET_OS_PROCESS_SIGNALED == statusType)) |
1682 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | 1708 | { |
1683 | _("Service `%s' took %s to terminate\n"), | 1709 | double utime = ru.ru_utime.tv_sec + (ru.ru_utime.tv_usec / 10e6); |
1710 | double stime = ru.ru_stime.tv_sec + (ru.ru_stime.tv_usec / 10e6); | ||
1711 | fprintf (wait_file, | ||
1712 | "%s(%u) %.3f %.3f %llu %llu %llu %llu %llu\n", | ||
1713 | pos->binary, | ||
1714 | (unsigned int) pid, | ||
1715 | utime, | ||
1716 | stime, | ||
1717 | (unsigned long long) ru.ru_maxrss, | ||
1718 | (unsigned long long) ru.ru_inblock, | ||
1719 | (unsigned long long) ru.ru_oublock, | ||
1720 | (unsigned long long) ru.ru_nvcsw, | ||
1721 | (unsigned long long) ru.ru_nivcsw); | ||
1722 | } | ||
1723 | } | ||
1724 | else /* continue with JUST this "if" as "else" (intentionally no brackets!) */ | ||
1725 | #endif | ||
1726 | if ((GNUNET_SYSERR == (ret = GNUNET_OS_process_status (pos->proc, | ||
1727 | &statusType, | ||
1728 | &statusCode))) || | ||
1729 | (ret == GNUNET_NO) || (statusType == GNUNET_OS_PROCESS_STOPPED) || | ||
1730 | (statusType == GNUNET_OS_PROCESS_UNKNOWN) || | ||
1731 | (statusType == GNUNET_OS_PROCESS_RUNNING)) | ||
1732 | continue; | ||
1733 | |||
1734 | if (statusType == GNUNET_OS_PROCESS_EXITED) | ||
1735 | { | ||
1736 | statstr = _ (/* process termination method */ "exit"); | ||
1737 | statcode = statusCode; | ||
1738 | } | ||
1739 | else if (statusType == GNUNET_OS_PROCESS_SIGNALED) | ||
1740 | { | ||
1741 | statstr = _ (/* process termination method */ "signal"); | ||
1742 | statcode = statusCode; | ||
1743 | } | ||
1744 | else | ||
1745 | { | ||
1746 | statstr = _ (/* process termination method */ "unknown"); | ||
1747 | statcode = 0; | ||
1748 | } | ||
1749 | if (0 != pos->killed_at.abs_value_us) | ||
1750 | { | ||
1751 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1752 | _ ("Service `%s' took %s to terminate\n"), | ||
1753 | pos->name, | ||
1754 | GNUNET_STRINGS_relative_time_to_string ( | ||
1755 | GNUNET_TIME_absolute_get_duration (pos->killed_at), | ||
1756 | GNUNET_YES)); | ||
1757 | } | ||
1758 | GNUNET_OS_process_destroy (pos->proc); | ||
1759 | pos->proc = NULL; | ||
1760 | broadcast_status (pos->name, GNUNET_ARM_SERVICE_STOPPED, NULL); | ||
1761 | if (NULL != pos->killing_client) | ||
1762 | { | ||
1763 | signal_result (pos->killing_client, | ||
1684 | pos->name, | 1764 | pos->name, |
1685 | GNUNET_STRINGS_relative_time_to_string( | 1765 | pos->killing_client_request_id, |
1686 | GNUNET_TIME_absolute_get_duration(pos->killed_at), | 1766 | GNUNET_ARM_RESULT_STOPPED); |
1687 | GNUNET_YES)); | 1767 | pos->killing_client = NULL; |
1688 | } | 1768 | pos->killing_client_request_id = 0; |
1689 | GNUNET_OS_process_destroy(pos->proc); | 1769 | } |
1690 | pos->proc = NULL; | 1770 | if (GNUNET_YES != in_shutdown) |
1691 | broadcast_status(pos->name, GNUNET_ARM_SERVICE_STOPPED, NULL); | 1771 | { |
1692 | if (NULL != pos->killing_client) | 1772 | pos->last_exit_status = statcode; |
1693 | { | 1773 | if ((statusType == GNUNET_OS_PROCESS_EXITED) && (statcode == 0)) |
1694 | signal_result(pos->killing_client, | 1774 | { |
1695 | pos->name, | 1775 | /* process terminated normally, allow restart at any time */ |
1696 | pos->killing_client_request_id, | 1776 | pos->restart_at.abs_value_us = 0; |
1697 | GNUNET_ARM_RESULT_STOPPED); | 1777 | GNUNET_log ( |
1698 | pos->killing_client = NULL; | 1778 | GNUNET_ERROR_TYPE_INFO, |
1699 | pos->killing_client_request_id = 0; | 1779 | _ ("Service `%s' terminated normally, will restart at any time\n"), |
1700 | } | 1780 | pos->name); |
1701 | if (GNUNET_YES != in_shutdown) | 1781 | /* process can still be re-started on-demand, ensure it is re-started if there is demand */ |
1782 | for (sli = pos->listen_head; NULL != sli; sli = sli->next) | ||
1702 | { | 1783 | { |
1703 | if ((statusType == GNUNET_OS_PROCESS_EXITED) && (statcode == 0)) | 1784 | GNUNET_break (NULL == sli->accept_task); |
1704 | { | 1785 | sli->accept_task = |
1705 | /* process terminated normally, allow restart at any time */ | 1786 | GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, |
1706 | pos->restart_at.abs_value_us = 0; | 1787 | sli->listen_socket, |
1707 | GNUNET_log( | 1788 | &accept_connection, |
1708 | GNUNET_ERROR_TYPE_INFO, | 1789 | sli); |
1709 | _("Service `%s' terminated normally, will restart at any time\n"), | ||
1710 | pos->name); | ||
1711 | /* process can still be re-started on-demand, ensure it is re-started if there is demand */ | ||
1712 | for (sli = pos->listen_head; NULL != sli; sli = sli->next) | ||
1713 | { | ||
1714 | GNUNET_break(NULL == sli->accept_task); | ||
1715 | sli->accept_task = | ||
1716 | GNUNET_SCHEDULER_add_read_net(GNUNET_TIME_UNIT_FOREVER_REL, | ||
1717 | sli->listen_socket, | ||
1718 | &accept_connection, | ||
1719 | sli); | ||
1720 | } | ||
1721 | } | ||
1722 | else | ||
1723 | { | ||
1724 | GNUNET_log( | ||
1725 | GNUNET_ERROR_TYPE_INFO, | ||
1726 | _("Service `%s' terminated with status %s/%d, will restart in %s\n"), | ||
1727 | pos->name, | ||
1728 | statstr, | ||
1729 | statcode, | ||
1730 | GNUNET_STRINGS_relative_time_to_string(pos->backoff, GNUNET_YES)); | ||
1731 | { | ||
1732 | /* Reduce backoff based on runtime of the process, | ||
1733 | so that there is a cool-down if a process actually | ||
1734 | runs for a while. */ | ||
1735 | struct GNUNET_TIME_Relative runtime; | ||
1736 | unsigned int minutes; | ||
1737 | |||
1738 | runtime = GNUNET_TIME_absolute_get_duration(pos->restart_at); | ||
1739 | minutes = | ||
1740 | runtime.rel_value_us / GNUNET_TIME_UNIT_MINUTES.rel_value_us; | ||
1741 | if (minutes > 31) | ||
1742 | pos->backoff = GNUNET_TIME_UNIT_ZERO; | ||
1743 | else | ||
1744 | pos->backoff.rel_value_us <<= minutes; | ||
1745 | } | ||
1746 | /* schedule restart */ | ||
1747 | pos->restart_at = GNUNET_TIME_relative_to_absolute(pos->backoff); | ||
1748 | pos->backoff = GNUNET_TIME_STD_BACKOFF(pos->backoff); | ||
1749 | if (NULL != child_restart_task) | ||
1750 | GNUNET_SCHEDULER_cancel(child_restart_task); | ||
1751 | child_restart_task = | ||
1752 | GNUNET_SCHEDULER_add_with_priority(GNUNET_SCHEDULER_PRIORITY_IDLE, | ||
1753 | &delayed_restart_task, | ||
1754 | NULL); | ||
1755 | } | ||
1756 | } | 1790 | } |
1791 | } | ||
1757 | else | 1792 | else |
1793 | { | ||
1794 | GNUNET_log ( | ||
1795 | GNUNET_ERROR_TYPE_WARNING, | ||
1796 | _ ("Service `%s' terminated with status %s/%d, will restart in %s\n"), | ||
1797 | pos->name, | ||
1798 | statstr, | ||
1799 | statcode, | ||
1800 | GNUNET_STRINGS_relative_time_to_string (pos->backoff, GNUNET_YES)); | ||
1758 | { | 1801 | { |
1759 | free_service(pos); | 1802 | /* Reduce backoff based on runtime of the process, |
1803 | so that there is a cool-down if a process actually | ||
1804 | runs for a while. */ | ||
1805 | struct GNUNET_TIME_Relative runtime; | ||
1806 | unsigned int minutes; | ||
1807 | |||
1808 | runtime = GNUNET_TIME_absolute_get_duration (pos->restart_at); | ||
1809 | minutes = | ||
1810 | runtime.rel_value_us / GNUNET_TIME_UNIT_MINUTES.rel_value_us; | ||
1811 | if (minutes > 31) | ||
1812 | pos->backoff = GNUNET_TIME_UNIT_ZERO; | ||
1813 | else | ||
1814 | pos->backoff.rel_value_us <<= minutes; | ||
1760 | } | 1815 | } |
1816 | /* schedule restart */ | ||
1817 | pos->restart_at = GNUNET_TIME_relative_to_absolute (pos->backoff); | ||
1818 | pos->backoff = GNUNET_TIME_STD_BACKOFF (pos->backoff); | ||
1819 | if (NULL != child_restart_task) | ||
1820 | GNUNET_SCHEDULER_cancel (child_restart_task); | ||
1821 | child_restart_task = | ||
1822 | GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, | ||
1823 | &delayed_restart_task, | ||
1824 | NULL); | ||
1825 | } | ||
1761 | } | 1826 | } |
1827 | else | ||
1828 | { | ||
1829 | free_service (pos); | ||
1830 | } | ||
1831 | } | ||
1762 | child_death_task = | 1832 | child_death_task = |
1763 | GNUNET_SCHEDULER_add_read_file(GNUNET_TIME_UNIT_FOREVER_REL, | 1833 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, |
1764 | pr, | 1834 | pr, |
1765 | &maint_child_death, | 1835 | &maint_child_death, |
1766 | NULL); | 1836 | NULL); |
1767 | if ((NULL == running_head) && (GNUNET_YES == in_shutdown)) | 1837 | if ((NULL == running_head) && (GNUNET_YES == in_shutdown)) |
1768 | do_shutdown(); | 1838 | do_shutdown (); |
1769 | else if (GNUNET_YES == in_shutdown) | 1839 | else if (GNUNET_YES == in_shutdown) |
1770 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 1840 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1771 | "Delaying shutdown after child's death, still have %u children\n", | 1841 | "Delaying shutdown after child's death, still have %u children\n", |
1772 | list_count(running_head)); | 1842 | list_count (running_head)); |
1773 | } | 1843 | } |
1774 | 1844 | ||
1775 | 1845 | ||
@@ -1778,17 +1848,17 @@ maint_child_death(void *cls) | |||
1778 | * respective handler by writing to the trigger pipe. | 1848 | * respective handler by writing to the trigger pipe. |
1779 | */ | 1849 | */ |
1780 | static void | 1850 | static void |
1781 | sighandler_child_death() | 1851 | sighandler_child_death () |
1782 | { | 1852 | { |
1783 | static char c; | 1853 | static char c; |
1784 | int old_errno = errno; /* back-up errno */ | 1854 | int old_errno = errno; /* back-up errno */ |
1785 | 1855 | ||
1786 | GNUNET_break( | 1856 | GNUNET_break ( |
1787 | 1 == | 1857 | 1 == |
1788 | GNUNET_DISK_file_write(GNUNET_DISK_pipe_handle(sigpipe, | 1858 | GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle (sigpipe, |
1789 | GNUNET_DISK_PIPE_END_WRITE), | 1859 | GNUNET_DISK_PIPE_END_WRITE), |
1790 | &c, | 1860 | &c, |
1791 | sizeof(c))); | 1861 | sizeof(c))); |
1792 | errno = old_errno; /* restore errno */ | 1862 | errno = old_errno; /* restore errno */ |
1793 | } | 1863 | } |
1794 | 1864 | ||
@@ -1802,7 +1872,7 @@ sighandler_child_death() | |||
1802 | * @return #GNUNET_OK (continue) | 1872 | * @return #GNUNET_OK (continue) |
1803 | */ | 1873 | */ |
1804 | static void | 1874 | static void |
1805 | setup_service(void *cls, const char *section) | 1875 | setup_service (void *cls, const char *section) |
1806 | { | 1876 | { |
1807 | struct ServiceList *sl; | 1877 | struct ServiceList *sl; |
1808 | char *binary; | 1878 | char *binary; |
@@ -1812,94 +1882,94 @@ setup_service(void *cls, const char *section) | |||
1812 | socklen_t *addr_lens; | 1882 | socklen_t *addr_lens; |
1813 | int ret; | 1883 | int ret; |
1814 | 1884 | ||
1815 | (void)cls; | 1885 | (void) cls; |
1816 | if (0 == strcasecmp(section, "arm")) | 1886 | if (0 == strcasecmp (section, "arm")) |
1817 | return; | 1887 | return; |
1818 | if (GNUNET_OK != | 1888 | if (GNUNET_OK != |
1819 | GNUNET_CONFIGURATION_get_value_string(cfg, section, "BINARY", &binary)) | 1889 | GNUNET_CONFIGURATION_get_value_string (cfg, section, "BINARY", &binary)) |
1820 | { | 1890 | { |
1821 | /* not a service section */ | 1891 | /* not a service section */ |
1822 | return; | 1892 | return; |
1823 | } | 1893 | } |
1824 | if ((GNUNET_YES == | 1894 | if ((GNUNET_YES == |
1825 | GNUNET_CONFIGURATION_have_value(cfg, section, "RUN_PER_USER")) && | 1895 | GNUNET_CONFIGURATION_have_value (cfg, section, "RUN_PER_USER")) && |
1826 | (GNUNET_YES == | 1896 | (GNUNET_YES == |
1827 | GNUNET_CONFIGURATION_get_value_yesno(cfg, section, "RUN_PER_USER"))) | 1897 | GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "RUN_PER_USER"))) |
1898 | { | ||
1899 | if (GNUNET_NO == start_user) | ||
1828 | { | 1900 | { |
1829 | if (GNUNET_NO == start_user) | 1901 | GNUNET_free (binary); |
1830 | { | 1902 | return; /* user service, and we don't deal with those */ |
1831 | GNUNET_free(binary); | ||
1832 | return; /* user service, and we don't deal with those */ | ||
1833 | } | ||
1834 | } | 1903 | } |
1904 | } | ||
1835 | else | 1905 | else |
1906 | { | ||
1907 | if (GNUNET_NO == start_system) | ||
1836 | { | 1908 | { |
1837 | if (GNUNET_NO == start_system) | 1909 | GNUNET_free (binary); |
1838 | { | 1910 | return; /* system service, and we don't deal with those */ |
1839 | GNUNET_free(binary); | ||
1840 | return; /* system service, and we don't deal with those */ | ||
1841 | } | ||
1842 | } | 1911 | } |
1843 | sl = find_service(section); | 1912 | } |
1913 | sl = find_service (section); | ||
1844 | if (NULL != sl) | 1914 | if (NULL != sl) |
1845 | { | 1915 | { |
1846 | /* got the same section twice!? */ | 1916 | /* got the same section twice!? */ |
1847 | GNUNET_break(0); | 1917 | GNUNET_break (0); |
1848 | GNUNET_free(binary); | 1918 | GNUNET_free (binary); |
1849 | return; | 1919 | return; |
1850 | } | 1920 | } |
1851 | config = NULL; | 1921 | config = NULL; |
1852 | if (((GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(cfg, | 1922 | if (((GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, |
1853 | section, | 1923 | section, |
1854 | "CONFIG", | 1924 | "CONFIG", |
1855 | &config)) && | 1925 | &config)) && |
1856 | (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(cfg, | 1926 | (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, |
1857 | "PATHS", | 1927 | "PATHS", |
1858 | "DEFAULTCONFIG", | 1928 | "DEFAULTCONFIG", |
1859 | &config))) || | 1929 | &config))) || |
1860 | (0 != stat(config, &sbuf))) | 1930 | (0 != stat (config, &sbuf))) |
1931 | { | ||
1932 | if (NULL != config) | ||
1861 | { | 1933 | { |
1862 | if (NULL != config) | 1934 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING, |
1863 | { | 1935 | section, |
1864 | GNUNET_log_config_invalid(GNUNET_ERROR_TYPE_WARNING, | 1936 | "CONFIG", |
1865 | section, | 1937 | strerror (errno)); |
1866 | "CONFIG", | 1938 | GNUNET_free (config); |
1867 | strerror(errno)); | 1939 | config = NULL; |
1868 | GNUNET_free(config); | ||
1869 | config = NULL; | ||
1870 | } | ||
1871 | } | 1940 | } |
1872 | sl = GNUNET_new(struct ServiceList); | 1941 | } |
1873 | sl->name = GNUNET_strdup(section); | 1942 | sl = GNUNET_new (struct ServiceList); |
1943 | sl->name = GNUNET_strdup (section); | ||
1874 | sl->binary = binary; | 1944 | sl->binary = binary; |
1875 | sl->config = config; | 1945 | sl->config = config; |
1876 | sl->backoff = GNUNET_TIME_UNIT_MILLISECONDS; | 1946 | sl->backoff = GNUNET_TIME_UNIT_MILLISECONDS; |
1877 | sl->restart_at = GNUNET_TIME_UNIT_FOREVER_ABS; | 1947 | sl->restart_at = GNUNET_TIME_UNIT_FOREVER_ABS; |
1878 | if (GNUNET_CONFIGURATION_have_value(cfg, section, "PIPECONTROL")) | 1948 | if (GNUNET_CONFIGURATION_have_value (cfg, section, "PIPECONTROL")) |
1879 | sl->pipe_control = | 1949 | sl->pipe_control = |
1880 | GNUNET_CONFIGURATION_get_value_yesno(cfg, section, "PIPECONTROL"); | 1950 | GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "PIPECONTROL"); |
1881 | GNUNET_CONTAINER_DLL_insert(running_head, running_tail, sl); | 1951 | GNUNET_CONTAINER_DLL_insert (running_head, running_tail, sl); |
1882 | if (GNUNET_YES == | 1952 | if (GNUNET_YES == |
1883 | GNUNET_CONFIGURATION_get_value_yesno(cfg, section, "IMMEDIATE_START")) | 1953 | GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "IMMEDIATE_START")) |
1884 | { | 1954 | { |
1885 | sl->force_start = GNUNET_YES; | 1955 | sl->force_start = GNUNET_YES; |
1886 | if (GNUNET_YES == | 1956 | if (GNUNET_YES == |
1887 | GNUNET_CONFIGURATION_get_value_yesno(cfg, section, "NOARMBIND")) | 1957 | GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "NOARMBIND")) |
1888 | return; | 1958 | return; |
1889 | } | 1959 | } |
1890 | else | 1960 | else |
1891 | { | 1961 | { |
1892 | if (GNUNET_YES != | 1962 | if (GNUNET_YES != |
1893 | GNUNET_CONFIGURATION_get_value_yesno(cfg, section, "START_ON_DEMAND")) | 1963 | GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "START_ON_DEMAND")) |
1894 | return; | 1964 | return; |
1895 | } | 1965 | } |
1896 | if (0 >= (ret = get_server_addresses(section, cfg, &addrs, &addr_lens))) | 1966 | if (0 >= (ret = get_server_addresses (section, cfg, &addrs, &addr_lens))) |
1897 | return; | 1967 | return; |
1898 | /* this will free (or capture) addrs[i] */ | 1968 | /* this will free (or capture) addrs[i] */ |
1899 | for (unsigned int i = 0; i < (unsigned int)ret; i++) | 1969 | for (unsigned int i = 0; i < (unsigned int) ret; i++) |
1900 | create_listen_socket(addrs[i], addr_lens[i], sl); | 1970 | create_listen_socket (addrs[i], addr_lens[i], sl); |
1901 | GNUNET_free(addrs); | 1971 | GNUNET_free (addrs); |
1902 | GNUNET_free(addr_lens); | 1972 | GNUNET_free (addr_lens); |
1903 | } | 1973 | } |
1904 | 1974 | ||
1905 | 1975 | ||
@@ -1912,16 +1982,16 @@ setup_service(void *cls, const char *section) | |||
1912 | * @return @a client | 1982 | * @return @a client |
1913 | */ | 1983 | */ |
1914 | static void * | 1984 | static void * |
1915 | client_connect_cb(void *cls, | 1985 | client_connect_cb (void *cls, |
1916 | struct GNUNET_SERVICE_Client *client, | 1986 | struct GNUNET_SERVICE_Client *client, |
1917 | struct GNUNET_MQ_Handle *mq) | 1987 | struct GNUNET_MQ_Handle *mq) |
1918 | { | 1988 | { |
1919 | /* All clients are considered to be of the "monitor" kind | 1989 | /* All clients are considered to be of the "monitor" kind |
1920 | * (that is, they don't affect ARM shutdown). | 1990 | * (that is, they don't affect ARM shutdown). |
1921 | */ | 1991 | */ |
1922 | (void)cls; | 1992 | (void) cls; |
1923 | (void)mq; | 1993 | (void) mq; |
1924 | GNUNET_SERVICE_client_mark_monitor(client); | 1994 | GNUNET_SERVICE_client_mark_monitor (client); |
1925 | return client; | 1995 | return client; |
1926 | } | 1996 | } |
1927 | 1997 | ||
@@ -1934,12 +2004,12 @@ client_connect_cb(void *cls, | |||
1934 | * @param app_ctx must match @a client | 2004 | * @param app_ctx must match @a client |
1935 | */ | 2005 | */ |
1936 | static void | 2006 | static void |
1937 | client_disconnect_cb(void *cls, | 2007 | client_disconnect_cb (void *cls, |
1938 | struct GNUNET_SERVICE_Client *client, | 2008 | struct GNUNET_SERVICE_Client *client, |
1939 | void *app_ctx) | 2009 | void *app_ctx) |
1940 | { | 2010 | { |
1941 | (void)cls; | 2011 | (void) cls; |
1942 | GNUNET_assert(client == app_ctx); | 2012 | GNUNET_assert (client == app_ctx); |
1943 | for (struct ServiceList *sl = running_head; NULL != sl; sl = sl->next) | 2013 | for (struct ServiceList *sl = running_head; NULL != sl; sl = sl->next) |
1944 | if (sl->killing_client == client) | 2014 | if (sl->killing_client == client) |
1945 | sl->killing_client = NULL; | 2015 | sl->killing_client = NULL; |
@@ -1955,18 +2025,18 @@ client_disconnect_cb(void *cls, | |||
1955 | * #GNUNET_SYSERR to close it (signal serious error) | 2025 | * #GNUNET_SYSERR to close it (signal serious error) |
1956 | */ | 2026 | */ |
1957 | static void | 2027 | static void |
1958 | handle_monitor(void *cls, const struct GNUNET_MessageHeader *message) | 2028 | handle_monitor (void *cls, const struct GNUNET_MessageHeader *message) |
1959 | { | 2029 | { |
1960 | struct GNUNET_SERVICE_Client *client = cls; | 2030 | struct GNUNET_SERVICE_Client *client = cls; |
1961 | 2031 | ||
1962 | (void)message; | 2032 | (void) message; |
1963 | /* FIXME: might want to start by letting monitor know about | 2033 | /* FIXME: might want to start by letting monitor know about |
1964 | services that are already running */ | 2034 | services that are already running */ |
1965 | /* Removal is handled by the server implementation, internally. */ | 2035 | /* Removal is handled by the server implementation, internally. */ |
1966 | GNUNET_notification_context_add(notifier, | 2036 | GNUNET_notification_context_add (notifier, |
1967 | GNUNET_SERVICE_client_get_mq(client)); | 2037 | GNUNET_SERVICE_client_get_mq (client)); |
1968 | broadcast_status("arm", GNUNET_ARM_SERVICE_MONITORING_STARTED, client); | 2038 | broadcast_status ("arm", GNUNET_ARM_SERVICE_MONITORING_STARTED, client); |
1969 | GNUNET_SERVICE_client_continue(client); | 2039 | GNUNET_SERVICE_client_continue (client); |
1970 | } | 2040 | } |
1971 | 2041 | ||
1972 | 2042 | ||
@@ -1978,71 +2048,71 @@ handle_monitor(void *cls, const struct GNUNET_MessageHeader *message) | |||
1978 | * @param c configuration to use | 2048 | * @param c configuration to use |
1979 | */ | 2049 | */ |
1980 | static void | 2050 | static void |
1981 | run(void *cls, | 2051 | run (void *cls, |
1982 | const struct GNUNET_CONFIGURATION_Handle *c, | 2052 | const struct GNUNET_CONFIGURATION_Handle *c, |
1983 | struct GNUNET_SERVICE_Handle *serv) | 2053 | struct GNUNET_SERVICE_Handle *serv) |
1984 | { | 2054 | { |
1985 | struct ServiceList *sl; | 2055 | struct ServiceList *sl; |
1986 | 2056 | ||
1987 | (void)cls; | 2057 | (void) cls; |
1988 | cfg = c; | 2058 | cfg = c; |
1989 | service = serv; | 2059 | service = serv; |
1990 | GNUNET_SCHEDULER_add_shutdown(&shutdown_task, NULL); | 2060 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); |
1991 | child_death_task = GNUNET_SCHEDULER_add_read_file( | 2061 | child_death_task = GNUNET_SCHEDULER_add_read_file ( |
1992 | GNUNET_TIME_UNIT_FOREVER_REL, | 2062 | GNUNET_TIME_UNIT_FOREVER_REL, |
1993 | GNUNET_DISK_pipe_handle(sigpipe, GNUNET_DISK_PIPE_END_READ), | 2063 | GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ), |
1994 | &maint_child_death, | 2064 | &maint_child_death, |
1995 | NULL); | 2065 | NULL); |
1996 | #if HAVE_WAIT4 | 2066 | #if HAVE_WAIT4 |
1997 | if (GNUNET_OK == | 2067 | if (GNUNET_OK == |
1998 | GNUNET_CONFIGURATION_get_value_filename(cfg, | 2068 | GNUNET_CONFIGURATION_get_value_filename (cfg, |
1999 | "ARM", | 2069 | "ARM", |
2000 | "RESOURCE_DIAGNOSTICS", | 2070 | "RESOURCE_DIAGNOSTICS", |
2001 | &wait_filename)) | 2071 | &wait_filename)) |
2072 | { | ||
2073 | wait_file = fopen (wait_filename, "w"); | ||
2074 | if (NULL == wait_file) | ||
2002 | { | 2075 | { |
2003 | wait_file = fopen(wait_filename, "w"); | 2076 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, |
2004 | if (NULL == wait_file) | 2077 | "fopen", |
2005 | { | 2078 | wait_filename); |
2006 | GNUNET_log_strerror_file(GNUNET_ERROR_TYPE_ERROR, | ||
2007 | "fopen", | ||
2008 | wait_filename); | ||
2009 | } | ||
2010 | } | 2079 | } |
2080 | } | ||
2011 | #endif | 2081 | #endif |
2012 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, | 2082 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, |
2013 | "ARM", | 2083 | "ARM", |
2014 | "GLOBAL_PREFIX", | 2084 | "GLOBAL_PREFIX", |
2015 | &prefix_command)) | 2085 | &prefix_command)) |
2016 | prefix_command = GNUNET_strdup(""); | 2086 | prefix_command = GNUNET_strdup (""); |
2017 | else | 2087 | else |
2018 | prefix_command = GNUNET_CONFIGURATION_expand_dollar(cfg, prefix_command); | 2088 | prefix_command = GNUNET_CONFIGURATION_expand_dollar (cfg, prefix_command); |
2019 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, | 2089 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, |
2020 | "ARM", | 2090 | "ARM", |
2021 | "GLOBAL_POSTFIX", | 2091 | "GLOBAL_POSTFIX", |
2022 | &final_option)) | 2092 | &final_option)) |
2023 | final_option = GNUNET_strdup(""); | 2093 | final_option = GNUNET_strdup (""); |
2024 | else | 2094 | else |
2025 | final_option = GNUNET_CONFIGURATION_expand_dollar(cfg, final_option); | 2095 | final_option = GNUNET_CONFIGURATION_expand_dollar (cfg, final_option); |
2026 | start_user = | 2096 | start_user = |
2027 | GNUNET_CONFIGURATION_get_value_yesno(cfg, "ARM", "START_USER_SERVICES"); | 2097 | GNUNET_CONFIGURATION_get_value_yesno (cfg, "ARM", "START_USER_SERVICES"); |
2028 | start_system = | 2098 | start_system = |
2029 | GNUNET_CONFIGURATION_get_value_yesno(cfg, "ARM", "START_SYSTEM_SERVICES"); | 2099 | GNUNET_CONFIGURATION_get_value_yesno (cfg, "ARM", "START_SYSTEM_SERVICES"); |
2030 | if ((GNUNET_NO == start_user) && (GNUNET_NO == start_system)) | 2100 | if ((GNUNET_NO == start_user) && (GNUNET_NO == start_system)) |
2031 | { | 2101 | { |
2032 | GNUNET_log( | 2102 | GNUNET_log ( |
2033 | GNUNET_ERROR_TYPE_ERROR, | 2103 | GNUNET_ERROR_TYPE_ERROR, |
2034 | "Please configure either START_USER_SERVICES or START_SYSTEM_SERVICES or both.\n"); | 2104 | "Please configure either START_USER_SERVICES or START_SYSTEM_SERVICES or both.\n"); |
2035 | GNUNET_SCHEDULER_shutdown(); | 2105 | GNUNET_SCHEDULER_shutdown (); |
2036 | global_ret = 1; | 2106 | global_ret = 1; |
2037 | return; | 2107 | return; |
2038 | } | 2108 | } |
2039 | GNUNET_CONFIGURATION_iterate_sections(cfg, &setup_service, NULL); | 2109 | GNUNET_CONFIGURATION_iterate_sections (cfg, &setup_service, NULL); |
2040 | 2110 | ||
2041 | /* start default services... */ | 2111 | /* start default services... */ |
2042 | for (sl = running_head; NULL != sl; sl = sl->next) | 2112 | for (sl = running_head; NULL != sl; sl = sl->next) |
2043 | if (GNUNET_YES == sl->force_start) | 2113 | if (GNUNET_YES == sl->force_start) |
2044 | start_process(sl, NULL, 0); | 2114 | start_process (sl, NULL, 0); |
2045 | notifier = GNUNET_notification_context_create(MAX_NOTIFY_QUEUE); | 2115 | notifier = GNUNET_notification_context_create (MAX_NOTIFY_QUEUE); |
2046 | } | 2116 | } |
2047 | 2117 | ||
2048 | 2118 | ||
@@ -2054,61 +2124,64 @@ run(void *cls, | |||
2054 | * @return 0 ok, 1 on error | 2124 | * @return 0 ok, 1 on error |
2055 | */ | 2125 | */ |
2056 | int | 2126 | int |
2057 | main(int argc, char *const *argv) | 2127 | main (int argc, char *const *argv) |
2058 | { | 2128 | { |
2059 | struct GNUNET_SIGNAL_Context *shc_chld; | 2129 | struct GNUNET_SIGNAL_Context *shc_chld; |
2060 | struct GNUNET_MQ_MessageHandler handlers[] = | 2130 | struct GNUNET_MQ_MessageHandler handlers[] = { |
2061 | { GNUNET_MQ_hd_var_size(start, | 2131 | GNUNET_MQ_hd_var_size (start, |
2062 | GNUNET_MESSAGE_TYPE_ARM_START, | 2132 | GNUNET_MESSAGE_TYPE_ARM_START, |
2063 | struct GNUNET_ARM_Message, | 2133 | struct GNUNET_ARM_Message, |
2064 | NULL), | 2134 | NULL), |
2065 | GNUNET_MQ_hd_var_size(stop, | 2135 | GNUNET_MQ_hd_var_size (stop, |
2066 | GNUNET_MESSAGE_TYPE_ARM_STOP, | 2136 | GNUNET_MESSAGE_TYPE_ARM_STOP, |
2067 | struct GNUNET_ARM_Message, | 2137 | struct GNUNET_ARM_Message, |
2068 | NULL), | 2138 | NULL), |
2069 | GNUNET_MQ_hd_fixed_size(monitor, | 2139 | GNUNET_MQ_hd_fixed_size (monitor, |
2070 | GNUNET_MESSAGE_TYPE_ARM_MONITOR, | 2140 | GNUNET_MESSAGE_TYPE_ARM_MONITOR, |
2071 | struct GNUNET_MessageHeader, | 2141 | struct GNUNET_MessageHeader, |
2072 | NULL), | 2142 | NULL), |
2073 | GNUNET_MQ_hd_fixed_size(list, | 2143 | GNUNET_MQ_hd_fixed_size (list, |
2074 | GNUNET_MESSAGE_TYPE_ARM_LIST, | 2144 | GNUNET_MESSAGE_TYPE_ARM_LIST, |
2075 | struct GNUNET_ARM_Message, | 2145 | struct GNUNET_ARM_Message, |
2076 | NULL), | 2146 | NULL), |
2077 | GNUNET_MQ_hd_fixed_size(test, | 2147 | GNUNET_MQ_hd_fixed_size (test, |
2078 | GNUNET_MESSAGE_TYPE_ARM_TEST, | 2148 | GNUNET_MESSAGE_TYPE_ARM_TEST, |
2079 | struct GNUNET_MessageHeader, | 2149 | struct GNUNET_MessageHeader, |
2080 | NULL), | 2150 | NULL), |
2081 | GNUNET_MQ_handler_end() }; | 2151 | GNUNET_MQ_handler_end () |
2082 | 2152 | }; | |
2083 | sigpipe = GNUNET_DISK_pipe(GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_NO); | 2153 | |
2084 | GNUNET_assert(NULL != sigpipe); | 2154 | sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_NO); |
2155 | GNUNET_assert (NULL != sigpipe); | ||
2085 | shc_chld = | 2156 | shc_chld = |
2086 | GNUNET_SIGNAL_handler_install(GNUNET_SIGCHLD, &sighandler_child_death); | 2157 | GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, |
2087 | if (0 != GNUNET_SERVICE_run_(argc, | 2158 | &sighandler_child_death); |
2088 | argv, | 2159 | if (0 != GNUNET_SERVICE_run_ (argc, |
2089 | "arm", | 2160 | argv, |
2090 | GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN, | 2161 | "arm", |
2091 | &run, | 2162 | GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN |
2092 | &client_connect_cb, | 2163 | | GNUNET_SERVICE_OPTION_CLOSE_LSOCKS, |
2093 | &client_disconnect_cb, | 2164 | &run, |
2094 | NULL, | 2165 | &client_connect_cb, |
2095 | handlers)) | 2166 | &client_disconnect_cb, |
2167 | NULL, | ||
2168 | handlers)) | ||
2096 | global_ret = 2; | 2169 | global_ret = 2; |
2097 | #if HAVE_WAIT4 | 2170 | #if HAVE_WAIT4 |
2098 | if (NULL != wait_file) | 2171 | if (NULL != wait_file) |
2099 | { | 2172 | { |
2100 | fclose(wait_file); | 2173 | fclose (wait_file); |
2101 | wait_file = NULL; | 2174 | wait_file = NULL; |
2102 | } | 2175 | } |
2103 | if (NULL != wait_filename) | 2176 | if (NULL != wait_filename) |
2104 | { | 2177 | { |
2105 | GNUNET_free(wait_filename); | 2178 | GNUNET_free (wait_filename); |
2106 | wait_filename = NULL; | 2179 | wait_filename = NULL; |
2107 | } | 2180 | } |
2108 | #endif | 2181 | #endif |
2109 | GNUNET_SIGNAL_handler_uninstall(shc_chld); | 2182 | GNUNET_SIGNAL_handler_uninstall (shc_chld); |
2110 | shc_chld = NULL; | 2183 | shc_chld = NULL; |
2111 | GNUNET_DISK_pipe_close(sigpipe); | 2184 | GNUNET_DISK_pipe_close (sigpipe); |
2112 | sigpipe = NULL; | 2185 | sigpipe = NULL; |
2113 | return global_ret; | 2186 | return global_ret; |
2114 | } | 2187 | } |
@@ -2120,11 +2193,11 @@ main(int argc, char *const *argv) | |||
2120 | /** | 2193 | /** |
2121 | * MINIMIZE heap size (way below 128k) since this process doesn't need much. | 2194 | * MINIMIZE heap size (way below 128k) since this process doesn't need much. |
2122 | */ | 2195 | */ |
2123 | void __attribute__ ((constructor)) GNUNET_ARM_memory_init() | 2196 | void __attribute__ ((constructor)) GNUNET_ARM_memory_init () |
2124 | { | 2197 | { |
2125 | mallopt(M_TRIM_THRESHOLD, 4 * 1024); | 2198 | mallopt (M_TRIM_THRESHOLD, 4 * 1024); |
2126 | mallopt(M_TOP_PAD, 1 * 1024); | 2199 | mallopt (M_TOP_PAD, 1 * 1024); |
2127 | malloc_trim(0); | 2200 | malloc_trim (0); |
2128 | } | 2201 | } |
2129 | #endif | 2202 | #endif |
2130 | 2203 | ||