From 1b84258d3a3c9cb12ecb32cae26d64432aee8dff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A0=D1=83=D1=81=D0=BB=D0=B0=D0=BD=20=D0=98=D0=B6=D0=B1=D1=83=D0=BB=D0=B0=D1=82=D0=BE=D0=B2?= Date: Sun, 5 Dec 2010 05:38:20 +0300 Subject: [PATCH] Parent-child control pipes (ndurner's IO-based) --- src/arm/gnunet-service-arm.c | 6 +- src/core/test_core_api.c | 2 +- src/core/test_core_api_reliability.c | 2 +- src/core/test_core_api_start_only.c | 2 +- src/core/test_core_quota_compliance.c | 2 +- src/datastore/perf_datastore_api.c | 2 +- src/datastore/test_datastore_api.c | 2 +- src/datastore/test_datastore_api_management.c | 2 +- src/dht/test_dht_api.c | 2 +- src/fs/test_fs_download.c | 2 +- src/fs/test_fs_download_indexed.c | 2 +- src/fs/test_fs_download_persistence.c | 2 +- src/fs/test_fs_list_indexed.c | 2 +- src/fs/test_fs_namespace.c | 2 +- src/fs/test_fs_namespace_list_updateable.c | 2 +- src/fs/test_fs_publish.c | 2 +- src/fs/test_fs_publish_persistence.c | 2 +- src/fs/test_fs_search.c | 2 +- src/fs/test_fs_search_persistence.c | 2 +- src/fs/test_fs_start_stop.c | 2 +- src/fs/test_fs_unindex.c | 2 +- src/fs/test_fs_unindex_persistence.c | 2 +- src/hostlist/test_gnunet_daemon_hostlist.c | 2 +- .../test_gnunet_daemon_hostlist_learning.c | 4 +- src/include/gnunet_disk_lib.h | 17 +- src/include/gnunet_os_lib.h | 14 +- src/peerinfo/perf_peerinfo_api.c | 2 +- src/peerinfo/test_peerinfo_api.c | 2 +- src/statistics/test_statistics_api.c | 4 +- src/statistics/test_statistics_api_loop.c | 2 +- src/testing/testing.c | 4 +- src/transport/plugin_transport_tcp.c | 2 +- src/transport/plugin_transport_udp.c | 2 +- src/transport/test_quota_compliance.c | 2 +- src/transport/test_transport_api.c | 2 +- src/transport/test_transport_api_reliability.c | 2 +- src/util/crypto_random.c | 6 +- src/util/disk.c | 99 +++- src/util/network.c | 21 +- src/util/os_priority.c | 607 ++++++++++++++++++-- src/util/scheduler.c | 3 + src/util/test_os_start_process.c | 2 +- src/util/test_resolver_api.c | 2 +- src/vpn/gnunet-daemon-vpn.c | 4 +- 44 files changed, 730 insertions(+), 123 deletions(-) diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c index c967c64..e1f4dcb 100644 --- a/src/arm/gnunet-service-arm.c +++ b/src/arm/gnunet-service-arm.c @@ -198,7 +198,7 @@ config_change_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Restarting service `%s' due to configuration file change.\n")); - if (0 != GNUNET_OS_process_kill (pos->proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (pos->proc, SIGTERM, GNUNET_YES)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); else pos->backoff = GNUNET_TIME_UNIT_MILLISECONDS; @@ -579,7 +579,7 @@ stop_service (struct GNUNET_SERVER_Client *client, "Sending kill signal to service `%s', waiting for process to die.\n", servicename); #endif - if (0 != GNUNET_OS_process_kill (pos->proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (pos->proc, SIGTERM, GNUNET_YES)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); pos->next = running; running = pos; @@ -730,7 +730,7 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stopping service `%s'\n", pos->name); - if (0 != GNUNET_OS_process_kill (pos->proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (pos->proc, SIGTERM, GNUNET_YES)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); } pos = pos->next; diff --git a/src/core/test_core_api.c b/src/core/test_core_api.c index 814ebe8..286497a 100644 --- a/src/core/test_core_api.c +++ b/src/core/test_core_api.c @@ -322,7 +322,7 @@ static void stop_arm (struct PeerContext *p) { #if START_ARM - if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); diff --git a/src/core/test_core_api_reliability.c b/src/core/test_core_api_reliability.c index 9192c95..480ca75 100644 --- a/src/core/test_core_api_reliability.c +++ b/src/core/test_core_api_reliability.c @@ -477,7 +477,7 @@ static void stop_arm (struct PeerContext *p) { #if START_ARM - if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); diff --git a/src/core/test_core_api_start_only.c b/src/core/test_core_api_start_only.c index dc5e35b..f361528 100644 --- a/src/core/test_core_api_start_only.c +++ b/src/core/test_core_api_start_only.c @@ -215,7 +215,7 @@ stop_arm (struct PeerContext *p) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping peer\n"); #if START_ARM - if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); diff --git a/src/core/test_core_quota_compliance.c b/src/core/test_core_quota_compliance.c index 6c5a528..243e8df 100644 --- a/src/core/test_core_quota_compliance.c +++ b/src/core/test_core_quota_compliance.c @@ -665,7 +665,7 @@ static void stop_arm (struct PeerContext *p) { #if START_ARM - if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); diff --git a/src/datastore/perf_datastore_api.c b/src/datastore/perf_datastore_api.c index 1f7c828..aa0c932 100644 --- a/src/datastore/perf_datastore_api.c +++ b/src/datastore/perf_datastore_api.c @@ -391,7 +391,7 @@ check () GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "perf-datastore-api", "nohelp", options, &run, NULL); - if (0 != GNUNET_OS_process_kill (proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (proc, SIGTERM, GNUNET_NO)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); ok = 1; diff --git a/src/datastore/test_datastore_api.c b/src/datastore/test_datastore_api.c index 06abc0c..de04655 100644 --- a/src/datastore/test_datastore_api.c +++ b/src/datastore/test_datastore_api.c @@ -660,7 +660,7 @@ check () argv, "test-datastore-api", "nohelp", options, &run, NULL); #if START_DATASTORE - if (0 != GNUNET_OS_process_kill (proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (proc, SIGTERM, GNUNET_NO)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); ok = 1; diff --git a/src/datastore/test_datastore_api_management.c b/src/datastore/test_datastore_api_management.c index d17d8fb..03e14d6 100644 --- a/src/datastore/test_datastore_api_management.c +++ b/src/datastore/test_datastore_api_management.c @@ -370,7 +370,7 @@ check () GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-datastore-api", "nohelp", options, &run, NULL); - if (0 != GNUNET_OS_process_kill (proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (proc, SIGTERM, GNUNET_NO)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); ok = 1; diff --git a/src/dht/test_dht_api.c b/src/dht/test_dht_api.c index b82d8cd..ab1e65f 100644 --- a/src/dht/test_dht_api.c +++ b/src/dht/test_dht_api.c @@ -120,7 +120,7 @@ static void stop_arm (struct PeerContext *p) { #if START_ARM - if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); GNUNET_OS_process_wait (p->arm_proc); GNUNET_OS_process_close (p->arm_proc); diff --git a/src/fs/test_fs_download.c b/src/fs/test_fs_download.c index 549a2ee..0ea3e28 100644 --- a/src/fs/test_fs_download.c +++ b/src/fs/test_fs_download.c @@ -257,7 +257,7 @@ static void stop_arm (struct PeerContext *p) { #if START_ARM - if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); diff --git a/src/fs/test_fs_download_indexed.c b/src/fs/test_fs_download_indexed.c index 6e59f97..f35c4c7 100644 --- a/src/fs/test_fs_download_indexed.c +++ b/src/fs/test_fs_download_indexed.c @@ -259,7 +259,7 @@ static void stop_arm (struct PeerContext *p) { #if START_ARM - if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); diff --git a/src/fs/test_fs_download_persistence.c b/src/fs/test_fs_download_persistence.c index 66d1199..1bb0107 100644 --- a/src/fs/test_fs_download_persistence.c +++ b/src/fs/test_fs_download_persistence.c @@ -317,7 +317,7 @@ static void stop_arm (struct PeerContext *p) { #if START_ARM - if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); diff --git a/src/fs/test_fs_list_indexed.c b/src/fs/test_fs_list_indexed.c index 206e58b..2ced9ff 100644 --- a/src/fs/test_fs_list_indexed.c +++ b/src/fs/test_fs_list_indexed.c @@ -209,7 +209,7 @@ static void stop_arm (struct PeerContext *p) { #if START_ARM - if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); diff --git a/src/fs/test_fs_namespace.c b/src/fs/test_fs_namespace.c index 0d37aff..230e4d0 100644 --- a/src/fs/test_fs_namespace.c +++ b/src/fs/test_fs_namespace.c @@ -82,7 +82,7 @@ static void stop_arm (struct PeerContext *p) { #if START_ARM - if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); diff --git a/src/fs/test_fs_namespace_list_updateable.c b/src/fs/test_fs_namespace_list_updateable.c index 359800f..bd41595 100644 --- a/src/fs/test_fs_namespace_list_updateable.c +++ b/src/fs/test_fs_namespace_list_updateable.c @@ -86,7 +86,7 @@ static void stop_arm (struct PeerContext *p) { #if START_ARM - if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); diff --git a/src/fs/test_fs_publish.c b/src/fs/test_fs_publish.c index 327fa5a..2eb639c 100644 --- a/src/fs/test_fs_publish.c +++ b/src/fs/test_fs_publish.c @@ -195,7 +195,7 @@ static void stop_arm (struct PeerContext *p) { #if START_ARM - if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); diff --git a/src/fs/test_fs_publish_persistence.c b/src/fs/test_fs_publish_persistence.c index 52b2b27..c6283b2 100644 --- a/src/fs/test_fs_publish_persistence.c +++ b/src/fs/test_fs_publish_persistence.c @@ -252,7 +252,7 @@ static void stop_arm (struct PeerContext *p) { #if START_ARM - if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); diff --git a/src/fs/test_fs_search.c b/src/fs/test_fs_search.c index b003b75..6a49d63 100644 --- a/src/fs/test_fs_search.c +++ b/src/fs/test_fs_search.c @@ -200,7 +200,7 @@ static void stop_arm (struct PeerContext *p) { #if START_ARM - if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); diff --git a/src/fs/test_fs_search_persistence.c b/src/fs/test_fs_search_persistence.c index 4def3fe..4e90f15 100644 --- a/src/fs/test_fs_search_persistence.c +++ b/src/fs/test_fs_search_persistence.c @@ -269,7 +269,7 @@ static void stop_arm (struct PeerContext *p) { #if START_ARM - if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); diff --git a/src/fs/test_fs_start_stop.c b/src/fs/test_fs_start_stop.c index 71043bf..126a4cc 100644 --- a/src/fs/test_fs_start_stop.c +++ b/src/fs/test_fs_start_stop.c @@ -72,7 +72,7 @@ static void stop_arm (struct PeerContext *p) { #if START_ARM - if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); diff --git a/src/fs/test_fs_unindex.c b/src/fs/test_fs_unindex.c index e2c0e86..899bed9 100644 --- a/src/fs/test_fs_unindex.c +++ b/src/fs/test_fs_unindex.c @@ -205,7 +205,7 @@ static void stop_arm (struct PeerContext *p) { #if START_ARM - if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); diff --git a/src/fs/test_fs_unindex_persistence.c b/src/fs/test_fs_unindex_persistence.c index eec1815..fa7c503 100644 --- a/src/fs/test_fs_unindex_persistence.c +++ b/src/fs/test_fs_unindex_persistence.c @@ -273,7 +273,7 @@ static void stop_arm (struct PeerContext *p) { #if START_ARM - if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); diff --git a/src/hostlist/test_gnunet_daemon_hostlist.c b/src/hostlist/test_gnunet_daemon_hostlist.c index b3859f6..7b8009d 100644 --- a/src/hostlist/test_gnunet_daemon_hostlist.c +++ b/src/hostlist/test_gnunet_daemon_hostlist.c @@ -154,7 +154,7 @@ waitpid_task (void *cls, #if START_ARM GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Killing ARM process.\n"); - if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); diff --git a/src/hostlist/test_gnunet_daemon_hostlist_learning.c b/src/hostlist/test_gnunet_daemon_hostlist_learning.c index 6f66b9c..5438a3c 100644 --- a/src/hostlist/test_gnunet_daemon_hostlist_learning.c +++ b/src/hostlist/test_gnunet_daemon_hostlist_learning.c @@ -133,7 +133,7 @@ static void shutdown_testcase() #if START_ARM GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Killing hostlist server ARM process.\n"); - if (0 != GNUNET_OS_process_kill (adv_peer.arm_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (adv_peer.arm_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); if (GNUNET_OS_process_wait(adv_peer.arm_proc) != GNUNET_OK) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); @@ -147,7 +147,7 @@ static void shutdown_testcase() #if START_ARM GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Killing hostlist client ARM process.\n"); - if (0 != GNUNET_OS_process_kill (learn_peer.arm_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (learn_peer.arm_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); if (GNUNET_OS_process_wait(learn_peer.arm_proc) != GNUNET_OK) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); diff --git a/src/include/gnunet_disk_lib.h b/src/include/gnunet_disk_lib.h index a59d10e..744eb05 100644 --- a/src/include/gnunet_disk_lib.h +++ b/src/include/gnunet_disk_lib.h @@ -643,13 +643,24 @@ int GNUNET_DISK_file_unmap (struct GNUNET_DISK_MapHandle *h); int GNUNET_DISK_file_sync (const struct GNUNET_DISK_FileHandle *h); /** - * Creates a named pipe/FIFO - * @param fn name of the named pipe + * Creates a named pipe/FIFO and opens it + * @param fn pointer to the name of the named pipe or to NULL * @param flags open flags * @param perm access permissions * @return pipe handle on success, NULL on error */ -struct GNUNET_DISK_FileHandle *GNUNET_DISK_npipe_open (const char *fn, +struct GNUNET_DISK_FileHandle *GNUNET_DISK_npipe_open (char **fn, + enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm); + +/** + * Opens already existing named pipe/FIFO + * + * @param fn name of an existing named pipe + * @param flags open flags + * @param perm access permissions + * @return pipe handle on success, NULL on error + */ +struct GNUNET_DISK_FileHandle *GNUNET_DISK_npipe_open_existing (const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm); /** diff --git a/src/include/gnunet_os_lib.h b/src/include/gnunet_os_lib.h index 5ff2b48..8d18c6e 100644 --- a/src/include/gnunet_os_lib.h +++ b/src/include/gnunet_os_lib.h @@ -192,9 +192,13 @@ struct GNUNET_OS_Process *GNUNET_OS_process_current (void); * * @param proc pointer to process structure * @param sig signal + * @param time_out GNUNET_YES to add a scheduler task that will kill() the + * process directly if signaling via control pipe times out, GNUNET_NO + * otherwise. Use GNUNET_NO when running outside of a scheduler, or + * when you are going to use GNUNET_OS_process_wait() right away. * @return 0 on success, -1 on error */ -int GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, int sig); +int GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, int sig, int time_out); /** @@ -274,6 +278,14 @@ int GNUNET_OS_process_status (struct GNUNET_OS_Process *proc, int GNUNET_OS_process_wait (struct GNUNET_OS_Process *proc); +/** + * Connects this process to its parent via pipe + */ +void +GNUNET_OS_install_parent_control_handler (void *cls, + const struct + GNUNET_SCHEDULER_TaskContext * tc); + #if 0 /* keep Emacsens' auto-indent happy */ { #endif diff --git a/src/peerinfo/perf_peerinfo_api.c b/src/peerinfo/perf_peerinfo_api.c index fe1851a..c503e83 100755 --- a/src/peerinfo/perf_peerinfo_api.c +++ b/src/peerinfo/perf_peerinfo_api.c @@ -185,7 +185,7 @@ check () numpeers, NUM_REQUESTS * NUM_REQUESTS / 2); #if START_SERVICE - if (0 != GNUNET_OS_process_kill (proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (proc, SIGTERM, GNUNET_NO)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); ok = 1; diff --git a/src/peerinfo/test_peerinfo_api.c b/src/peerinfo/test_peerinfo_api.c index fdd0dc4..2bcc982 100644 --- a/src/peerinfo/test_peerinfo_api.c +++ b/src/peerinfo/test_peerinfo_api.c @@ -182,7 +182,7 @@ check () GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test-peerinfo-api", "nohelp", options, &run, &ok); - if (0 != GNUNET_OS_process_kill (proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (proc, SIGTERM, GNUNET_NO)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); ok = 1; diff --git a/src/statistics/test_statistics_api.c b/src/statistics/test_statistics_api.c index 9e43663..42a511c 100644 --- a/src/statistics/test_statistics_api.c +++ b/src/statistics/test_statistics_api.c @@ -166,7 +166,7 @@ check () GNUNET_PROGRAM_run (5, argv, "test-statistics-api", "nohelp", options, &run, &ok); #if START_SERVICE - if (0 != GNUNET_OS_process_kill (proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (proc, SIGTERM, GNUNET_NO)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); ok = 1; @@ -190,7 +190,7 @@ check () GNUNET_PROGRAM_run (5, argv, "test-statistics-api", "nohelp", options, &run_more, &ok); #if START_SERVICE - if (0 != GNUNET_OS_process_kill (proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (proc, SIGTERM, GNUNET_NO)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); ok = 1; diff --git a/src/statistics/test_statistics_api_loop.c b/src/statistics/test_statistics_api_loop.c index 02f4aca..f03a869 100644 --- a/src/statistics/test_statistics_api_loop.c +++ b/src/statistics/test_statistics_api_loop.c @@ -106,7 +106,7 @@ check () GNUNET_PROGRAM_run (3, argv, "test-statistics-api", "nohelp", options, &run, &ok); #if START_SERVICE - if (0 != GNUNET_OS_process_kill (proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (proc, SIGTERM, GNUNET_NO)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); ok = 1; diff --git a/src/testing/testing.c b/src/testing/testing.c index 0204f31..f0f3402 100644 --- a/src/testing/testing.c +++ b/src/testing/testing.c @@ -401,7 +401,7 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) d->cb = NULL; GNUNET_DISK_pipe_close (d->pipe_stdout); d->pipe_stdout = NULL; - (void) GNUNET_OS_process_kill (d->proc, SIGKILL); + (void) GNUNET_OS_process_kill (d->proc, SIGKILL, GNUNET_NO); GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (d->proc)); GNUNET_OS_process_close (d->proc); d->proc = NULL; @@ -411,7 +411,7 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } GNUNET_DISK_pipe_close (d->pipe_stdout); d->pipe_stdout = NULL; - (void) GNUNET_OS_process_kill (d->proc, SIGKILL); + (void) GNUNET_OS_process_kill (d->proc, SIGKILL, GNUNET_NO); GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (d->proc)); GNUNET_OS_process_close (d->proc); d->proc = NULL; diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index 627cb6b..6dcb21f 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c @@ -3012,7 +3012,7 @@ libgnunet_plugin_transport_tcp_done (void *cls) if (plugin->behind_nat == GNUNET_YES) { - if (0 != GNUNET_OS_process_kill (plugin->server_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (plugin->server_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); GNUNET_OS_process_wait (plugin->server_proc); GNUNET_OS_process_close (plugin->server_proc); diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c index 4bf66f2..3595028 100644 --- a/src/transport/plugin_transport_udp.c +++ b/src/transport/plugin_transport_udp.c @@ -522,7 +522,7 @@ udp_transport_server_stop (void *cls) } if (plugin->behind_nat == GNUNET_YES) { - if (0 != GNUNET_OS_process_kill (plugin->server_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (plugin->server_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); GNUNET_OS_process_wait (plugin->server_proc); GNUNET_OS_process_close (plugin->server_proc); diff --git a/src/transport/test_quota_compliance.c b/src/transport/test_quota_compliance.c index e4b7280..db92140 100644 --- a/src/transport/test_quota_compliance.c +++ b/src/transport/test_quota_compliance.c @@ -196,7 +196,7 @@ static void stop_arm (struct PeerContext *p) { #if START_ARM - if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); GNUNET_OS_process_wait (p->arm_proc); GNUNET_OS_process_close (p->arm_proc); diff --git a/src/transport/test_transport_api.c b/src/transport/test_transport_api.c index 5bf57b8..0d8adf7 100644 --- a/src/transport/test_transport_api.c +++ b/src/transport/test_transport_api.c @@ -118,7 +118,7 @@ static void stop_arm (struct PeerContext *p) { #if START_ARM - if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); GNUNET_OS_process_wait (p->arm_proc); GNUNET_OS_process_close (p->arm_proc); diff --git a/src/transport/test_transport_api_reliability.c b/src/transport/test_transport_api_reliability.c index 31c5970..d7bfa6e 100644 --- a/src/transport/test_transport_api_reliability.c +++ b/src/transport/test_transport_api_reliability.c @@ -139,7 +139,7 @@ static void stop_arm (struct PeerContext *p) { #if START_ARM - if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); GNUNET_OS_process_wait (p->arm_proc); GNUNET_OS_process_close (p->arm_proc); diff --git a/src/util/crypto_random.c b/src/util/crypto_random.c index 6228174..8d8179d 100644 --- a/src/util/crypto_random.c +++ b/src/util/crypto_random.c @@ -208,7 +208,7 @@ entropy_generator (void *cls, { if (genproc != NULL) { - if (0 != GNUNET_OS_process_kill (genproc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (genproc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "kill"); GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (genproc)); GNUNET_OS_process_close (genproc); @@ -226,7 +226,7 @@ entropy_generator (void *cls, GNUNET_break (0); return; } - if (0 != GNUNET_OS_process_kill (genproc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (genproc, SIGTERM, GNUNET_NO)) GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "kill"); GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (genproc)); GNUNET_OS_process_close (genproc); @@ -247,7 +247,7 @@ killfind () { if (genproc != NULL) { - GNUNET_OS_process_kill (genproc, SIGKILL); + GNUNET_OS_process_kill (genproc, SIGKILL, GNUNET_NO); GNUNET_OS_process_close (genproc); genproc = NULL; } diff --git a/src/util/disk.c b/src/util/disk.c index 0b37da8..5d35fa0 100644 --- a/src/util/disk.c +++ b/src/util/disk.c @@ -31,6 +31,7 @@ #include "gnunet_disk_lib.h" #include "gnunet_scheduler_lib.h" #include "gnunet_strings_lib.h" +#include "gnunet_crypto_lib.h" #include "disk.h" @@ -1877,20 +1878,20 @@ GNUNET_DISK_pipe_close (struct GNUNET_DISK_PipeHandle *p) /** - * Creates a named pipe/FIFO - * @param fn name of the named pipe + * Creates a named pipe/FIFO and opens it + * @param fn pointer to the name of the named pipe or to NULL * @param flags open flags * @param perm access permissions * @return pipe handle on success, NULL on error */ struct GNUNET_DISK_FileHandle * -GNUNET_DISK_npipe_open (const char *fn, +GNUNET_DISK_npipe_open (char **fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm) { -#ifdef MINGW +#if WINDOWS && !defined(__CYGWIN__) struct GNUNET_DISK_FileHandle *ret; - HANDLE h; + HANDLE h = NULL; DWORD openMode; char *name; @@ -1905,21 +1906,50 @@ GNUNET_DISK_npipe_open (const char *fn, if (flags & GNUNET_DISK_OPEN_FAILIFEXISTS) openMode |= FILE_FLAG_FIRST_PIPE_INSTANCE; - GNUNET_asprintf(&name, "\\\\.\\pipe\\pipename\\%s", fn); - h = CreateNamedPipe (fn, openMode | FILE_FLAG_OVERLAPPED, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 2, 1, 1, 0, NULL); - GNUNET_free(name); - if (h == NULL) + while (h == NULL) { - SetErrnoFromWinError(GetLastError()); - return NULL; + name = NULL; + if (*fn != NULL) + { + GNUNET_asprintf(&name, "\\\\.\\pipe\\%.246s", fn); + h = CreateNamedPipe (name, openMode | FILE_FLAG_OVERLAPPED, + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 2, 1, 1, 0, NULL); + } + else + { + GNUNET_asprintf(fn, "\\\\.\\pipe\\gnunet-%llu", + GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX)); + h = CreateNamedPipe (*fn, openMode | FILE_FLAG_OVERLAPPED, + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 2, 1, 1, 0, NULL); + } + if (name) + GNUNET_free(name); + /* don't re-set name to NULL yet */ + if (h == INVALID_HANDLE_VALUE) + { + SetErrnoFromWinError(GetLastError()); + if (name == NULL) + { + GNUNET_free (*fn); + *fn = NULL; + if (errno != EEXIST) + return NULL; + } + else + return NULL; + } } + errno = 0; ret = GNUNET_malloc(sizeof(*ret)); ret->h = h; + ret->type = GNUNET_PIPE; return ret; #else + /* FIXME: if fn is NULL generate a fn (something in /usr/share/gnunet/, + * with a random number attached + */ if (mkfifo(fn, translate_unix_perms(perm)) == -1) { if ( (errno != EEXIST) || @@ -1933,6 +1963,51 @@ GNUNET_DISK_npipe_open (const char *fn, } /** + * Opens already existing named pipe/FIFO + * + * @param fn name of an existing named pipe + * @param flags open flags + * @param perm access permissions + * @return pipe handle on success, NULL on error + */ +struct GNUNET_DISK_FileHandle * +GNUNET_DISK_npipe_open_existing (const char *fn, + enum GNUNET_DISK_OpenFlags flags, + enum GNUNET_DISK_AccessPermissions perm) +{ +#if WINDOWS && !defined(__CYGWIN__) + struct GNUNET_DISK_FileHandle *ret; + HANDLE h; + DWORD openMode; + + openMode = 0; + if (flags & GNUNET_DISK_OPEN_READWRITE) + openMode = GENERIC_WRITE | GENERIC_READ; + else if (flags & GNUNET_DISK_OPEN_READ) + openMode = GENERIC_READ; + else if (flags & GNUNET_DISK_OPEN_WRITE) + openMode = GENERIC_WRITE; + + h = CreateFile (fn, openMode, 0, NULL, OPEN_EXISTING, + FILE_FLAG_OVERLAPPED | FILE_READ_ATTRIBUTES, NULL); + if (h == INVALID_HANDLE_VALUE) + { + SetErrnoFromWinError(GetLastError()); + return NULL; + } + + ret = GNUNET_malloc(sizeof(*ret)); + ret->h = h; + ret->type = GNUNET_PIPE; + + return ret; +#else + flags = flags & (~GNUNET_DISK_OPEN_FAILIFEXISTS); + return GNUNET_DISK_file_open(fn, flags, perm); +#endif +} + +/** * Closes a named pipe/FIFO * @param pipe named pipe * @return GNUNET_OK on success, GNUNET_SYSERR otherwise diff --git a/src/util/network.c b/src/util/network.c index 3b76a35..c2929ac 100644 --- a/src/util/network.c +++ b/src/util/network.c @@ -1125,15 +1125,26 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds, { if (!PeekNamedPipe (fh->h, NULL, 0, NULL, &dwBytes, NULL)) { - retcode = -1; - SetErrnoFromWinError (GetLastError ()); + DWORD error_code = GetLastError (); + switch (error_code) + { + case ERROR_BROKEN_PIPE: + GNUNET_CONTAINER_slist_add (handles_read, + GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT, + fh, sizeof (struct GNUNET_DISK_FileHandle)); + retcode++; + break; + default: + retcode = -1; + SetErrnoFromWinError (error_code); #if DEBUG_NETWORK - GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, - "PeekNamedPipe"); + GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, + "PeekNamedPipe"); #endif - goto select_loop_end; + goto select_loop_end; + } } else if (dwBytes) diff --git a/src/util/os_priority.c b/src/util/os_priority.c index fb6c292..7a6fc4a 100644 --- a/src/util/os_priority.c +++ b/src/util/os_priority.c @@ -27,29 +27,106 @@ #include "platform.h" #include "gnunet_common.h" #include "gnunet_os_lib.h" +#include "gnunet_scheduler_lib.h" #include "disk.h" +#define GNUNET_OS_CONTROL_PIPE "GNUNET_OS_CONTROL_PIPE" + struct GNUNET_OS_Process { pid_t pid; #if WINDOWS HANDLE handle; #endif + int sig; + struct GNUNET_DISK_FileHandle *control_pipe; + GNUNET_SCHEDULER_TaskIdentifier kill_timeout_task; }; static struct GNUNET_OS_Process current_process; -#if WINDOWS +/** + * This handler is called when there are control data to be read on the pipe + */ void -GNUNET_OS_process_set_handle(struct GNUNET_OS_Process *proc, HANDLE handle) +GNUNET_OS_parent_control_handler (void *cls, + const struct + GNUNET_SCHEDULER_TaskContext * tc) { - if (proc->handle != NULL) - CloseHandle (proc->handle); - proc->handle = handle; + struct GNUNET_DISK_FileHandle *control_pipe = (struct GNUNET_DISK_FileHandle *) cls; + unsigned char code; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_OS_parent_control_handler is invoked because of %d\n", tc->reason); + + if (tc->reason & (GNUNET_SCHEDULER_REASON_SHUTDOWN | GNUNET_SCHEDULER_REASON_TIMEOUT | GNUNET_SCHEDULER_REASON_PREREQ_DONE)) + { + GNUNET_DISK_npipe_close (control_pipe); + } + else + { + if (GNUNET_DISK_file_read (control_pipe, &code, sizeof (char)) != sizeof (char)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "GNUNET_DISK_file_read have failed, errno = %d. Closing the control pipe.\n", errno); + GNUNET_DISK_npipe_close (control_pipe); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got control code %d\n", code); + switch (code) + { + case 0: + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Raising SIGTERM\n"); + raise (SIGTERM); + break; + case 1: + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Raising SIGKILL\n"); + raise (SIGKILL); + break; + case 255: + /* read more bytes - a possibility for extended signals + * in case 254 different valies is not enough + */ + break; + default: + break; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Re-scheduling the parent control handler pipe\n"); + GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, control_pipe, GNUNET_OS_parent_control_handler, control_pipe); + } + } } -#endif +/** + * Connects this process to its parent via pipe + */ +void +GNUNET_OS_install_parent_control_handler (void *cls, + const struct + GNUNET_SCHEDULER_TaskContext * tc) +{ + char *env_buf; + struct GNUNET_DISK_FileHandle *control_pipe = NULL; + + env_buf = getenv (GNUNET_OS_CONTROL_PIPE); + if (env_buf == NULL || strlen (env_buf) <= 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not installing a handler because %s=%s\n", GNUNET_OS_CONTROL_PIPE, env_buf); + return; + } + + control_pipe = GNUNET_DISK_npipe_open_existing (env_buf, + GNUNET_DISK_OPEN_READ, + GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); + if (control_pipe == NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to open the pipe `%s'\n", env_buf); + return; + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding parent control handler pipe `%s' to the scheduler\n", env_buf); + GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, control_pipe, GNUNET_OS_parent_control_handler, control_pipe); +} /** * Get process structure for current process @@ -71,34 +148,129 @@ GNUNET_OS_process_current () return ¤t_process; } -int -GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, int sig) +struct GNUNET_OS_process_kill_timeout_cls { -#if WINDOWS - if (sig == SIGKILL || sig == SIGTERM) + struct GNUNET_OS_Process *proc; + int sig; +}; + +void +GNUNET_OS_process_kill_timeout (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_OS_Process *proc = (struct GNUNET_OS_Process *) cls; + enum GNUNET_OS_ProcessStatusType type; + unsigned long code; + unsigned char c; + size_t s; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_OS_process_kill_timeout() is called because of %d\n", tc->reason); + + if (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT && GNUNET_OS_process_status (proc, &type, &code) == GNUNET_NO) { - HANDLE h = proc->handle; - if (NULL == h) + switch (proc->sig) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Invalid process information {%d, %08X}\n"), - proc->pid, - h); - return -1; + case SIGTERM: + c = 0; + break; + case SIGKILL: + c = 1; + break; } - if (!TerminateProcess (h, 0)) + + s = sizeof (c); + if (GNUNET_DISK_file_write (proc->control_pipe, &c, s) != s) { - SetErrnoFromWinError (GetLastError ()); - return -1; +#if !WINDOWS || defined(__CYGWIN__) + kill (proc->pid, proc->sig); +#else + DWORD dwresult, error_code; + BOOL bresult; + SetLastError (0); + dwresult = WaitForSingleObject (proc->handle, 0); + error_code = GetLastError (); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Woke up, returned %d, GLE is %d\n", dwresult, error_code); + if (WAIT_OBJECT_0 != dwresult || error_code != NO_ERROR) + { + SetLastError (0); + bresult = TerminateProcess (proc->handle, 0); + error_code = GetLastError (); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "TerminateProcess for the child returned %d, GLE is %d\n", bresult, + error_code); + } +#endif + } + } + proc->kill_timeout_task = 0; +} + +int +GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, int sig, int time_out) +{ + unsigned char c; + size_t s; + int res = 0; + int ret = 0; + + if (proc->kill_timeout_task) + { + GNUNET_SCHEDULER_cancel (proc->kill_timeout_task); + proc->kill_timeout_task = 0; + } + + switch (sig) + { + case SIGTERM: + c = 0; + break; + case SIGKILL: + c = 1; + break; + default: + errno = EINVAL; + return -1; + } + + s = sizeof (c); + ret = GNUNET_DISK_file_write (proc->control_pipe, &c, s); + if (ret != s) + { + if (errno == ECOMM) + { + /* Child process is not controllable via pipe */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Child process is not controllable, will kill it directly\n"); + if (time_out == GNUNET_YES) + { + proc->sig = sig; + proc->kill_timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply + (GNUNET_TIME_UNIT_SECONDS, 0), GNUNET_OS_process_kill_timeout, proc); + } + else + { + struct GNUNET_SCHEDULER_TaskContext tc; + tc.reason = GNUNET_SCHEDULER_REASON_TIMEOUT; + GNUNET_OS_process_kill_timeout (proc, &tc); + } } else - return 0; + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to write into control pipe , errno is %d\n", errno); + res = -1; + } } - errno = EINVAL; - return -1; -#else - return kill (proc->pid, sig); -#endif + else if (time_out == GNUNET_YES) + { + proc->sig = sig; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Wrote control code into control pipe, now waiting\n"); + proc->kill_timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply + (GNUNET_TIME_UNIT_SECONDS, 3), GNUNET_OS_process_kill_timeout, proc); + } + return res; } /** @@ -117,14 +289,18 @@ GNUNET_OS_process_get_pid (struct GNUNET_OS_Process *proc) void GNUNET_OS_process_close (struct GNUNET_OS_Process *proc) { -#if WINDOWS + if (proc->kill_timeout_task) + GNUNET_SCHEDULER_cancel (proc->kill_timeout_task); + if (proc->control_pipe) + GNUNET_DISK_npipe_close (proc->control_pipe); +#if WINDOWS && !defined(__CYGWIN__) if (proc->handle != NULL) CloseHandle (proc->handle); #endif GNUNET_free (proc); } -#if WINDOWS +#if WINDOWS && !defined(__CYGWIN__) #include "gnunet_signal_lib.h" extern GNUNET_SIGNAL_Handler w32_sigchld_handler; @@ -258,6 +434,105 @@ GNUNET_OS_set_process_priority (struct GNUNET_OS_Process *proc, return GNUNET_OK; } +#if WINDOWS && !defined(__CYGWIN__) +char * +CreateCustomEnvTable (char **vars) +{ + char *win32_env_table, *ptr, **var_ptr, *result, *result_ptr; + size_t tablesize = 0; + size_t items_count = 0; + size_t n_found = 0, n_var; + char *index = NULL; + size_t c; + size_t var_len; + char *var; + char *val; + win32_env_table = GetEnvironmentStringsA (); + if (win32_env_table == NULL) + return NULL; + for (c = 0, var_ptr = vars; *var_ptr; var_ptr += 2, c++); + n_var = c; + index = GNUNET_malloc (n_var); + for (c = 0; c < n_var; c++) + index[c] = 0; + for (items_count = 0, ptr = win32_env_table; ptr[0] != 0; items_count++) + { + size_t len = strlen (ptr); + int found = 0; + for (var_ptr = vars; *var_ptr; var_ptr++) + { + var = *var_ptr++; + val = *var_ptr; + var_len = strlen (var); + if (strncmp (var, ptr, var_len) == 0) + { + found = 1; + index[c] = 1; + tablesize += var_len + strlen (val) + 1; + break; + } + } + if (!found) + tablesize += len + 1; + ptr += len + 1; + } + for (n_found = 0, c = 0, var_ptr = vars; *var_ptr; var_ptr++, c++) + { + var = *var_ptr++; + val = *var_ptr; + if (index[c] != 1) + n_found += strlen (var) + strlen (val) + 1; + } + result = GNUNET_malloc (tablesize + n_found + 1); + for (result_ptr = result, ptr = win32_env_table; ptr[0] != 0;) + { + size_t len = strlen (ptr); + int found = 0; + for (c = 0, var_ptr = vars; *var_ptr; var_ptr++, c++) + { + var = *var_ptr++; + val = *var_ptr; + var_len = strlen (var); + if (strncmp (var, ptr, var_len) == 0) + { + found = 1; + break; + } + } + if (!found) + { + strcpy (result_ptr, ptr); + result_ptr += len + 1; + } + else + { + strcpy (result_ptr, var); + result_ptr += var_len; + strcpy (result_ptr, val); + result_ptr += strlen (val) + 1; + } + ptr += len + 1; + } + for (c = 0, var_ptr = vars; *var_ptr; var_ptr++, c++) + { + var = *var_ptr++; + val = *var_ptr; + var_len = strlen (var); + if (index[c] != 1) + { + strcpy (result_ptr, var); + result_ptr += var_len; + strcpy (result_ptr, val); + result_ptr += strlen (val) + 1; + } + } + FreeEnvironmentStrings (win32_env_table); + GNUNET_free (index); + *result_ptr = 0; + return result; +} +#endif + /** * Start a process. * @@ -273,10 +548,12 @@ GNUNET_OS_start_process (struct GNUNET_DISK_PipeHandle *pipe_stdin, const char *filename, ...) { va_list ap; + char *childpipename = NULL; + struct GNUNET_DISK_FileHandle *control_pipe = NULL; + struct GNUNET_OS_Process *gnunet_proc = NULL; #ifndef MINGW pid_t ret; - struct GNUNET_OS_Process *gnunet_proc = NULL; char **argv; int argc; int fd_stdout_write; @@ -284,6 +561,12 @@ GNUNET_OS_start_process (struct GNUNET_DISK_PipeHandle *pipe_stdin, int fd_stdin_read; int fd_stdin_write; + control_pipe = GNUNET_DISK_npipe_open (&childpipename, + GNUNET_DISK_OPEN_WRITE, GNUNET_DISK_PERM_USER_READ | + GNUNET_DISK_PERM_USER_WRITE); + if (control_pipe == NULL) + return NULL; + argc = 0; va_start (ap, filename); while (NULL != va_arg (ap, char *)) @@ -316,6 +599,7 @@ GNUNET_OS_start_process (struct GNUNET_DISK_PipeHandle *pipe_stdin, if (ret == -1) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fork"); + GNUNET_DISK_npipe_close (control_pipe); } else { @@ -337,11 +621,16 @@ GNUNET_OS_start_process (struct GNUNET_DISK_PipeHandle *pipe_stdin, #endif gnunet_proc = GNUNET_malloc (sizeof (struct GNUNET_OS_Process)); gnunet_proc->pid = ret; + gnunet_proc->control_pipe = control_pipe; } GNUNET_free (argv); + GNUNET_free (childpipename); return gnunet_proc; } + setenv (GNUNET_OS_CONTROL_PIPE, childpipename, 1); + GNUNET_free (childpipename); + if (pipe_stdout != NULL) { GNUNET_break (0 == close (fd_stdout_read)); @@ -367,23 +656,89 @@ GNUNET_OS_start_process (struct GNUNET_DISK_PipeHandle *pipe_stdin, char *cmd, *idx; STARTUPINFO start; PROCESS_INFORMATION proc; - struct GNUNET_OS_Process *gnunet_proc = NULL; HANDLE stdin_handle; HANDLE stdout_handle; char path[MAX_PATH + 1]; + char *our_env[3] = { NULL, NULL, NULL }; + char *env_block = NULL; + char *pathbuf; + DWORD pathbuf_len, alloc_len; + char *self_prefix; + char *bindir; + char *libdir; + char *ptr; + char *non_const_filename; + + /* Search in prefix dir (hopefully - the directory from which + * the current module was loaded), bindir and libdir, then in PATH + */ + self_prefix = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_SELF_PREFIX); + bindir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_BINDIR); + libdir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LIBDIR); + + pathbuf_len = GetEnvironmentVariableA ("PATH", (char *) &pathbuf, 0); + + alloc_len = pathbuf_len + 1 + strlen (self_prefix) + 1 + strlen (bindir) + 1 + strlen (libdir); + + pathbuf = GNUNET_malloc (alloc_len * sizeof (char)); + + ptr = pathbuf; + ptr += sprintf (pathbuf, "%s;%s;%s;", self_prefix, bindir, libdir); + GNUNET_free (self_prefix); + GNUNET_free (bindir); + GNUNET_free (libdir); + + alloc_len = GetEnvironmentVariableA ("PATH", ptr, pathbuf_len); + if (alloc_len != pathbuf_len - 1) + { + GNUNET_free (pathbuf); + errno = ENOSYS; /* PATH changed on the fly. What kind of error is that? */ + return NULL; + } + + cmdlen = strlen (filename); + if (cmdlen < 5 || strcmp (&filename[cmdlen - 4], ".exe") != 0) + GNUNET_asprintf (&non_const_filename, "%s.exe", filename); + else + GNUNET_asprintf (&non_const_filename, "%s", filename); + + /* Check that this is the full path. If it isn't, search. */ + if (non_const_filename[1] == ':') + snprintf (path, sizeof (path) / sizeof (char), "%s", non_const_filename); + else if (!SearchPathA (pathbuf, non_const_filename, NULL, sizeof (path) / sizeof (char), path, NULL)) + { + SetErrnoFromWinError (GetLastError ()); + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "SearchPath", non_const_filename); + GNUNET_free (non_const_filename); + GNUNET_free (pathbuf); + return NULL; + } + GNUNET_free (pathbuf); + GNUNET_free (non_const_filename); + cmdlen = 0; va_start (ap, filename); while (NULL != (arg = va_arg (ap, char *))) - cmdlen = cmdlen + strlen (arg) + 3; + { + if (cmdlen == 0) + cmdlen = cmdlen + strlen (path) + 3; + else + cmdlen = cmdlen + strlen (arg) + 3; + } va_end (ap); cmd = idx = GNUNET_malloc (sizeof (char) * (cmdlen + 1)); va_start (ap, filename); while (NULL != (arg = va_arg (ap, char *))) - idx += sprintf (idx, "\"%s\" ", arg); + { + if (idx == cmd) + idx += sprintf (idx, "\"%s\" ", path); + else + idx += sprintf (idx, "\"%s\" ", arg); + } va_end (ap); memset (&start, 0, sizeof (start)); @@ -404,28 +759,46 @@ GNUNET_OS_start_process (struct GNUNET_DISK_PipeHandle *pipe_stdin, start.hStdOutput = stdout_handle; } - if (32 >= (int) FindExecutableA (filename, NULL, path)) - { - SetErrnoFromWinError (GetLastError ()); - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "FindExecutable", filename); - return NULL; - } + control_pipe = GNUNET_DISK_npipe_open (&childpipename, + GNUNET_DISK_OPEN_WRITE, GNUNET_DISK_PERM_USER_READ | + GNUNET_DISK_PERM_USER_WRITE); + if (control_pipe == NULL) + { + GNUNET_free (cmd); + GNUNET_free (path); + return NULL; + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Opened the parent end of the pipe `%s'\n", childpipename); + + GNUNET_asprintf (&our_env[0], "%s=", GNUNET_OS_CONTROL_PIPE); + GNUNET_asprintf (&our_env[1], "%s", childpipename); + our_env[2] = NULL; + env_block = CreateCustomEnvTable (our_env); + GNUNET_free (our_env[0]); + GNUNET_free (our_env[1]); if (!CreateProcessA - (path, cmd, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &start, - &proc)) + (path, cmd, NULL, NULL, TRUE, DETACHED_PROCESS | CREATE_SUSPENDED, + env_block, NULL, &start, &proc)) { SetErrnoFromWinError (GetLastError ()); GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "CreateProcess", path); + GNUNET_free (env_block); + GNUNET_free (cmd); return NULL; } + GNUNET_free (env_block); + gnunet_proc = GNUNET_malloc (sizeof (struct GNUNET_OS_Process)); gnunet_proc->pid = proc.dwProcessId; gnunet_proc->handle = proc.hProcess; + gnunet_proc->control_pipe = control_pipe; CreateThread (NULL, 64000, ChildWaitThread, (void *) gnunet_proc, 0, NULL); + ResumeThread (proc.hThread); CloseHandle (proc.hThread); GNUNET_free (cmd); @@ -450,6 +823,9 @@ struct GNUNET_OS_Process * GNUNET_OS_start_process_v (const int *lsocks, const char *filename, char *const argv[]) { + struct GNUNET_DISK_FileHandle *control_pipe = NULL; + char *childpipename = NULL; + #ifndef MINGW pid_t ret; char lpid[16]; @@ -463,6 +839,12 @@ GNUNET_OS_start_process_v (const int *lsocks, int *lscp; unsigned int ls; + control_pipe = GNUNET_DISK_npipe_open (&childpipename, + GNUNET_DISK_OPEN_WRITE, GNUNET_DISK_PERM_USER_READ | + GNUNET_DISK_PERM_USER_WRITE); + if (control_pipe == NULL) + return NULL; + lscp = NULL; ls = 0; if (lsocks != NULL) @@ -482,6 +864,7 @@ GNUNET_OS_start_process_v (const int *lsocks, if (ret == -1) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fork"); + GNUNET_DISK_npipe_close (control_pipe); } else { @@ -498,10 +881,16 @@ GNUNET_OS_start_process_v (const int *lsocks, #endif gnunet_proc = GNUNET_malloc (sizeof (struct GNUNET_OS_Process)); gnunet_proc->pid = ret; + gnunet_proc->control_pipe = control_pipe; } GNUNET_array_grow (lscp, ls, 0); + GNUNET_free (childpipename); return gnunet_proc; } + + setenv (GNUNET_OS_CONTROL_PIPE, childpipename, 1); + GNUNET_free (childpipename); + if (lscp != NULL) { /* read systemd documentation... */ @@ -555,17 +944,68 @@ GNUNET_OS_start_process_v (const int *lsocks, STARTUPINFO start; PROCESS_INFORMATION proc; int argcount = 0; - char non_const_filename[MAX_PATH +1]; struct GNUNET_OS_Process *gnunet_proc = NULL; + char path[MAX_PATH + 1]; + + char *our_env[3] = { NULL, NULL, NULL }; + char *env_block = NULL; + char *pathbuf; + DWORD pathbuf_len, alloc_len; + char *self_prefix; + char *bindir; + char *libdir; + char *ptr; + char *non_const_filename; + GNUNET_assert (lsocks == NULL); - if (32 >= (int) FindExecutableA (filename, NULL, non_const_filename)) + /* Search in prefix dir (hopefully - the directory from which + * the current module was loaded), bindir and libdir, then in PATH + */ + self_prefix = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_SELF_PREFIX); + bindir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_BINDIR); + libdir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LIBDIR); + + pathbuf_len = GetEnvironmentVariableA ("PATH", (char *) &pathbuf, 0); + + alloc_len = pathbuf_len + 1 + strlen (self_prefix) + 1 + strlen (bindir) + 1 + strlen (libdir); + + pathbuf = GNUNET_malloc (alloc_len * sizeof (char)); + + ptr = pathbuf; + ptr += sprintf (pathbuf, "%s;%s;%s;", self_prefix, bindir, libdir); + GNUNET_free (self_prefix); + GNUNET_free (bindir); + GNUNET_free (libdir); + + alloc_len = GetEnvironmentVariableA ("PATH", ptr, pathbuf_len); + if (alloc_len != pathbuf_len - 1) + { + GNUNET_free (pathbuf); + errno = ENOSYS; /* PATH changed on the fly. What kind of error is that? */ + return NULL; + } + + cmdlen = strlen (filename); + if (cmdlen < 5 || strcmp (&filename[cmdlen - 4], ".exe") != 0) + GNUNET_asprintf (&non_const_filename, "%s.exe", filename); + else + GNUNET_asprintf (&non_const_filename, "%s", filename); + + /* Check that this is the full path. If it isn't, search. */ + if (non_const_filename[1] == ':') + snprintf (path, sizeof (path) / sizeof (char), "%s", non_const_filename); + else if (!SearchPathA (pathbuf, non_const_filename, NULL, sizeof (path) / sizeof (char), path, NULL)) { SetErrnoFromWinError (GetLastError ()); - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "FindExecutable", filename); + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "SearchPath", non_const_filename); + GNUNET_free (non_const_filename); + GNUNET_free (pathbuf); return NULL; } + GNUNET_free (pathbuf); + GNUNET_free (non_const_filename); /* Count the number of arguments */ arg = (char **) argv; @@ -583,7 +1023,10 @@ GNUNET_OS_start_process_v (const int *lsocks, arg = (char **) argv; while (*arg) { - non_const_argv[argcount] = GNUNET_strdup (*arg); + if (arg == argv) + non_const_argv[argcount] = GNUNET_strdup (path); + else + non_const_argv[argcount] = GNUNET_strdup (*arg); arg++; argcount++; } @@ -607,31 +1050,56 @@ GNUNET_OS_start_process_v (const int *lsocks, arg++; } + while (argcount > 0) + GNUNET_free (non_const_argv[--argcount]); + GNUNET_free (non_const_argv); + memset (&start, 0, sizeof (start)); start.cb = sizeof (start); + control_pipe = GNUNET_DISK_npipe_open (&childpipename, + GNUNET_DISK_OPEN_WRITE, GNUNET_DISK_PERM_USER_READ | + GNUNET_DISK_PERM_USER_WRITE); + if (control_pipe == NULL) + { + GNUNET_free (cmd); + GNUNET_free (path); + return NULL; + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Opened the parent end of the pipe `%s'\n", childpipename); + + GNUNET_asprintf (&our_env[0], "%s=", GNUNET_OS_CONTROL_PIPE); + GNUNET_asprintf (&our_env[1], "%s", childpipename); + our_env[2] = NULL; + env_block = CreateCustomEnvTable (our_env); + GNUNET_free (our_env[0]); + GNUNET_free (our_env[1]); + if (!CreateProcess - (non_const_filename, cmd, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &start, - &proc)) + (path, cmd, NULL, NULL, FALSE, DETACHED_PROCESS | CREATE_SUSPENDED, + env_block, NULL, &start, &proc)) { SetErrnoFromWinError (GetLastError ()); GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "CreateProcess"); + GNUNET_free (env_block); + GNUNET_free (cmd); return NULL; } + GNUNET_free (env_block); + gnunet_proc = GNUNET_malloc (sizeof (struct GNUNET_OS_Process)); gnunet_proc->pid = proc.dwProcessId; gnunet_proc->handle = proc.hProcess; + gnunet_proc->control_pipe = control_pipe; CreateThread (NULL, 64000, ChildWaitThread, (void *) gnunet_proc, 0, NULL); + ResumeThread (proc.hThread); CloseHandle (proc.hThread); GNUNET_free (cmd); - while (argcount > 0) - GNUNET_free (non_const_argv[--argcount]); - GNUNET_free (non_const_argv); - return gnunet_proc; #endif } @@ -741,8 +1209,13 @@ GNUNET_OS_process_status (struct GNUNET_OS_Process *proc, int GNUNET_OS_process_wait (struct GNUNET_OS_Process *proc) { - -#ifndef MINGW +#if !WINDOWS || defined(__CYGWIN__) + if (proc->kill_timeout_task) + { + GNUNET_SCHEDULER_cancel (proc->kill_timeout_task); + proc->kill_timeout_task = 0; + kill (proc->pid, proc->sig); + } pid_t pid = proc->pid; if (pid != waitpid (pid, NULL, 0)) return GNUNET_SYSERR; @@ -763,13 +1236,35 @@ GNUNET_OS_process_wait (struct GNUNET_OS_Process *proc) if (h == NULL) h = GetCurrentProcess (); - if (WAIT_OBJECT_0 != WaitForSingleObject (h, INFINITE)) + if (proc->kill_timeout_task) + { + GNUNET_SCHEDULER_cancel (proc->kill_timeout_task); + proc->kill_timeout_task = 0; + if (WAIT_OBJECT_0 != WaitForSingleObject (h, 4000)) { - SetErrnoFromWinError (GetLastError ()); - ret = GNUNET_SYSERR; + struct GNUNET_SCHEDULER_TaskContext tc; + tc.reason = GNUNET_SCHEDULER_REASON_TIMEOUT; + GNUNET_OS_process_kill_timeout (proc, &tc); + if (WAIT_OBJECT_0 != WaitForSingleObject (h, INFINITE)) + { + ret = GNUNET_SYSERR; + SetErrnoFromWinError (GetLastError ()); + } + else + ret = GNUNET_OK; } - else ret = GNUNET_OK; + } + else + { + if (WAIT_OBJECT_0 != WaitForSingleObject (h, INFINITE)) + { + SetErrnoFromWinError (GetLastError ()); + ret = GNUNET_SYSERR; + } + else + ret = GNUNET_OK; + } return ret; #endif diff --git a/src/util/scheduler.c b/src/util/scheduler.c index 13b3f85..353c7ea 100644 --- a/src/util/scheduler.c +++ b/src/util/scheduler.c @@ -741,6 +741,9 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *task_cls) GNUNET_SCHEDULER_add_continuation (task, task_cls, GNUNET_SCHEDULER_REASON_STARTUP); + GNUNET_SCHEDULER_add_continuation (GNUNET_OS_install_parent_control_handler, + NULL, GNUNET_SCHEDULER_REASON_STARTUP); + last_tr = 0; busy_wait_warning = 0; while ((pending != NULL) || diff --git a/src/util/test_os_start_process.c b/src/util/test_os_start_process.c index f82860e..d648a04 100644 --- a/src/util/test_os_start_process.c +++ b/src/util/test_os_start_process.c @@ -50,7 +50,7 @@ static void end_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - if (0 != GNUNET_OS_process_kill (proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (proc, SIGTERM, GNUNET_NO)) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); } diff --git a/src/util/test_resolver_api.c b/src/util/test_resolver_api.c index 3d1d544..8da5ae0 100644 --- a/src/util/test_resolver_api.c +++ b/src/util/test_resolver_api.c @@ -378,7 +378,7 @@ check() GNUNET_free(fn); GNUNET_assert(GNUNET_OK == GNUNET_PROGRAM_run((sizeof(argv) / sizeof(char *)) - 1, argv, "test-resolver-api", "nohelp", options, &run, &ok)); - if (0 != GNUNET_OS_process_kill (proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (proc, SIGTERM, GNUNET_NO)) { GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "kill"); ok = 1; diff --git a/src/vpn/gnunet-daemon-vpn.c b/src/vpn/gnunet-daemon-vpn.c index 3b3dbfa..bb41e0c 100644 --- a/src/vpn/gnunet-daemon-vpn.c +++ b/src/vpn/gnunet-daemon-vpn.c @@ -195,7 +195,7 @@ cleanup(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tskctx) { /* stop the helper */ if (helper_proc != NULL) { - GNUNET_OS_process_kill (helper_proc, SIGTERM); + GNUNET_OS_process_kill (helper_proc, SIGTERM, GNUNET_NO); GNUNET_OS_process_wait (helper_proc); GNUNET_OS_process_close (helper_proc); helper_proc = NULL; @@ -250,7 +250,7 @@ start_helper_and_schedule(void *cls, static void restart_helper(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tskctx) { // Kill the helper - GNUNET_OS_process_kill (helper_proc, SIGKILL); + GNUNET_OS_process_kill (helper_proc, SIGKILL, GNUNET_NO); GNUNET_OS_process_wait (helper_proc); GNUNET_OS_process_close (helper_proc); helper_proc = NULL; -- 1.7.3.1.msysgit.0