View Issue Details

IDProjectCategoryView StatusLast Update
0001614GNUnetobsoletepublic2024-05-03 13:51
ReporterLRN Assigned ToLRN  
PrioritynormalSeveritymajorReproducibilityalways
Status closedResolutionfixed 
Target VersionGit master 
Summary0001614: ARM fails to detect which child processes are still running
DescriptionThere's a mistype/bug in os_priority.c in invokation of GetExitCodeProcess() that makes GNUNET_OS_process_status() return 1 for any existing process. That's trivial to fix.

Also, a behavioristic error that causes GNUNET_OS_process_status() to return -1 (GNUNET_SYSERR) for any non-existing process (it doesn't matter whether or not this process never existed, or simply terminated). That happens because API function responsible for obtaining exit code of the process takes process handle, and it is impossible to obtain such handle for a process that was completely terminated (the subsystem scraped the object, since the object had no more open handles left).

There is also a problem that most mainstream win32 subsystem implementations will recycle process identifiers (and a particular implementation dating 2000 did that very aggressively), so there is a chance that a child process will terminate and a new (unrelated) process will be launched and will get the same (now free) process identifier, before ARM gets a chance to acknowledge child's demise. This way ARM will keep thinking that the child process is still running.

The patch (attached) adds a new type - GNUNET_OS_Process, which is a structure that contains OS-specific process information. When win32 subsystem is used, that includes HANDLE and process identifier. When POSIX system is used, GNUNET_OS_Process only contains process identifier. Several new (and some of the old) API functions in gnunetutil are able to create such structures (passed around as pointers) and to all necessary process operations (wait upon, kill or check status of the process) using these structures, hiding OS-specific implementation details from the user.
The advantage is that win32 version will retain the child process handle it receives from CreateProcess() and win32 implementation of said functions will use this handle to perform all necessary operations, instead of calling OpenProcess() every time to obtain a handle using process identifier - which, as was mentioned above, fails when process no longer exists. Holding a handle to a process ensures that process object won't fade away until ARM has a chance to check its status.

The disadvantage of this approach, other than the fact that there are 2-3 extra function calls and 1 extra function nesting for POSIX systems (PLIBC_KILL was a macro for kill(), while GNUNET_OS_process_kill () is a normal function that calls kill()), is that structures are allocated on the heap and have to be freed when no longer needed, which might, when left unchecked, lead to memory leaks and (for win32 subsystems) handle resource leaks.
Steps To ReproduceThe bugs mentioned are apparent whenever a child of gnunet-service-arm.exe dies - ARM will launch a new *batch* of processes instead of re-running the process that died.
Additional InformationComments are welcome.
TagsNo tags attached.
Attached Files
GNUNET_OS_Process.diff (101,402 bytes)   
Index: src/dht/test_dht_api.c
===================================================================
--- src/dht/test_dht_api.c	(revision 13533)
+++ src/dht/test_dht_api.c	(working copy)
@@ -85,7 +85,7 @@
   struct GNUNET_DHT_FindPeerHandle *find_peer_handle;
 
 #if START_ARM
-  pid_t arm_pid;
+  GNUNET_OS_Process *arm_proc;
 #endif
 };
 
@@ -121,9 +121,11 @@
 stop_arm (struct PeerContext *p)
 {
 #if START_ARM
-  if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  GNUNET_OS_process_wait (p->arm_pid);
+  GNUNET_OS_process_wait (p->arm_proc);
+  GNUNET_OS_process_close (p->arm_proc);
+  p->arm_proc = NULL;
 #endif
   GNUNET_CONFIGURATION_destroy (p->cfg);
 }
@@ -453,7 +455,7 @@
 {
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                         "gnunet-service-arm",
 #if VERBOSE_ARM
                                         "-L", "DEBUG",
Index: src/dht/Makefile.am
===================================================================
--- src/dht/Makefile.am	(revision 13533)
+++ src/dht/Makefile.am	(working copy)
@@ -192,13 +192,13 @@
  $(top_builddir)/src/dht/libgnunetdht.la \
  $(top_builddir)/src/dht/libgnunetdhtlog.la
 
-test_kademlia_end2end_SOURCES = \
- test_kademlia_end2end.c
-test_kademlia_end2end_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/testing/libgnunettesting.la \
- $(top_builddir)/src/dht/libgnunetdht.la \
- $(top_builddir)/src/dht/libgnunetdhtlog.la
+#test_kademlia_end2end_SOURCES = \
+# test_kademlia_end2end.c
+#test_kademlia_end2end_LDADD = \
+# $(top_builddir)/src/util/libgnunetutil.la \
+# $(top_builddir)/src/testing/libgnunettesting.la \
+# $(top_builddir)/src/dht/libgnunetdht.la \
+# $(top_builddir)/src/dht/libgnunetdhtlog.la
 
 EXTRA_DIST = \
   $(check_SCRIPTS) \
Index: src/arm/arm_api.c
===================================================================
--- src/arm/arm_api.c	(revision 13533)
+++ src/arm/arm_api.c	(working copy)
@@ -375,7 +375,7 @@
 		    const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   struct RequestContext *pos = cls;
-  pid_t pid;
+  GNUNET_OS_Process *proc;
   char *binary;
   char *config;
   char *loprefix;
@@ -454,7 +454,7 @@
                                                            )
     {
       /* we're clearly running a test, don't daemonize */
-      pid = do_start_process (NULL,
+      proc = do_start_process (NULL,
 			      loprefix,
 			      binary,
 			      "-c", config,
@@ -467,7 +467,7 @@
     }
   else
     {
-      pid = do_start_process (NULL,
+      proc = do_start_process (NULL,
 			      loprefix,
 			      binary,
 			      "-c", config,
@@ -482,7 +482,7 @@
   GNUNET_free (config);
   GNUNET_free (loprefix);
   GNUNET_free (lopostfix);
-  if (pid == -1)
+  if (proc == NULL)
     {
       if (pos->callback != NULL)
         pos->callback (pos->cls, GNUNET_SYSERR);
Index: src/arm/gnunet-service-arm.c
===================================================================
--- src/arm/gnunet-service-arm.c	(revision 13533)
+++ src/arm/gnunet-service-arm.c	(working copy)
@@ -91,9 +91,9 @@
   struct GNUNET_SERVER_Client *killing_client;
 
   /**
-   * Process ID of the child.
+   * Process structure pointer of the child.
    */
-  pid_t pid;
+  GNUNET_OS_Process *proc;
 
   /**
    * Last time the config of this service was
@@ -199,11 +199,11 @@
       /* FIXME: this test for config change is a bit too coarse grained */
       if ( (0 == STAT (pos->config, &sbuf)) && 
 	   (pos->mtime < sbuf.st_mtime) &&
-	   (pos->pid != 0) )
+	   (pos->proc != NULL) )
 	{
 	  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 		      _("Restarting service `%s' due to configuration file change.\n"));
-	  if (0 != PLIBC_KILL (pos->pid, SIGTERM))
+	  if (0 != GNUNET_OS_process_kill (pos->proc, SIGTERM))
 	    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
 	  else
 	    pos->backoff = GNUNET_TIME_UNIT_MILLISECONDS;
@@ -414,7 +414,7 @@
 	      sl->name, sl->binary, sl->config);
 #endif
   if (GNUNET_YES == use_debug)
-    sl->pid = do_start_process (lsocks,
+    sl->proc = do_start_process (lsocks,
 				loprefix,				
 				sl->binary,
 				"-c", sl->config,
@@ -422,19 +422,24 @@
 				options,
 				NULL);
   else
-    sl->pid = do_start_process (lsocks,
+    sl->proc = do_start_process (lsocks,
 				loprefix,
 				sl->binary,
 				"-c", sl->config,
 				options,
 				NULL);
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
-	      _("Starting service `%s' (PID: %d)\n"), 
-	      sl->name,
-	      (int) sl->pid);
+  if (sl->proc == NULL)
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
+	        _("Failed to start service `%s'\n"), 
+	        sl->name);
+  else
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
+	        _("Starting service `%s' (PID: %d)\n"), 
+	        sl->name,
+	        (int) GNUNET_OS_process_get_pid (sl->proc));
   GNUNET_free (loprefix);
   GNUNET_free (options);
-  /* FIXME: should check sl->pid */
+  /* FIXME: should check sl->proc */
 }
 
 
@@ -568,7 +573,7 @@
       running = pos;
       return;
     }
-  if (pos->pid == 0)
+  if (pos->proc == NULL)
     {
       /* process is in delayed restart, simply remove it! */
       free_entry (pos);
@@ -581,7 +586,7 @@
 	      "Sending kill signal to service `%s', waiting for process to die.\n",
 	      servicename);
 #endif
-  if (0 != PLIBC_KILL (pos->pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (pos->proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
   pos->next = running;
   running = pos;
@@ -653,7 +658,7 @@
 
 /**
  * Remove all entries for tasks that are not running
- * (pid = 0) from the running list (they will no longer
+ * (proc = NULL) from the running list (they will no longer
  * be restarted since we are shutting down).
  */
 static void
@@ -668,7 +673,7 @@
   while (NULL != pos)
     {
       next = pos->next;
-      if (pos->pid == 0)
+      if (pos->proc == NULL)
 	{
 	  if (prev == NULL)
 	    running = next;
@@ -727,13 +732,13 @@
   pos = running;
   while (NULL != pos)
     {
-      if (pos->pid != 0)
+      if (pos->proc != NULL)
 	{
 	  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
 		      "Stopping service `%s' (PID: %d)\n",
 		      pos->name,
-		      pos->pid);
-	  if (0 != PLIBC_KILL (pos->pid, SIGTERM))
+		      GNUNET_OS_process_get_pid (pos->proc));
+	  if (0 != GNUNET_OS_process_kill (pos->proc, SIGTERM))
 	    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
 	}
       pos = pos->next;
@@ -773,7 +778,7 @@
   pos = running;
   while (pos != NULL)
     {
-      if ( (pos->pid == 0) && 
+      if ( (pos->proc == NULL) && 
 	   (GNUNET_YES != in_shutdown) )
 	{
 	  if (GNUNET_TIME_absolute_get_remaining (pos->restartAt).rel_value == 0)
@@ -845,12 +850,12 @@
   while (NULL != (pos = next))
     {
       next = pos->next;
-      if (pos->pid == 0) 
+      if (pos->proc == NULL) 
 	{
 	  prev = pos;
 	  continue;
 	}
-      if ((GNUNET_SYSERR == (ret = GNUNET_OS_process_status (pos->pid,
+      if ((GNUNET_SYSERR == (ret = GNUNET_OS_process_status (pos->proc,
 							     &statusType,
 							     &statusCode))) ||
 	  ( (ret == GNUNET_NO) ||
@@ -876,7 +881,8 @@
 	  statstr = _( /* process termination method */ "unknown");
 	  statcode = 0;
 	}
-      pos->pid = 0;
+      GNUNET_OS_process_close (pos->proc);
+      pos->proc = NULL;
       if (NULL != pos->killing_client) 
 	{
 	  if (prev == NULL)
Index: src/arm/do_start_process.c
===================================================================
--- src/arm/do_start_process.c	(revision 13533)
+++ src/arm/do_start_process.c	(working copy)
@@ -12,7 +12,7 @@
  * @param ... more arguments, NULL terminated
  * @return PID of the started process, -1 on error
  */
-static pid_t
+static GNUNET_OS_Process *
 do_start_process (const int *lsocks,
 		  const char *first_arg, ...)
 {
@@ -24,7 +24,7 @@
   char *pos;
   char *cp;
   const char *last;
-  pid_t pid;
+  GNUNET_OS_Process *proc;
 
   argv_size = 1;
   va_start (ap, first_arg);
@@ -88,9 +88,9 @@
   while (NULL != (arg = (va_arg (ap, const char*))));
   va_end (ap);
   argv[argv_size] = NULL;
-  pid = GNUNET_OS_start_process_v (lsocks, argv[0], argv);
+  proc = GNUNET_OS_start_process_v (lsocks, argv[0], argv);
   while (argv_size > 0)
     GNUNET_free (argv[--argv_size]);
   GNUNET_free (argv);
-  return pid;
+  return proc;
 }
Index: src/include/gnunet_os_lib.h
===================================================================
--- src/include/gnunet_os_lib.h	(revision 13533)
+++ src/include/gnunet_os_lib.h	(working copy)
@@ -44,7 +44,12 @@
 #include "gnunet_configuration_lib.h"
 #include "gnunet_scheduler_lib.h"
 
+/**
+ * Process information (OS-dependent)
+ */
+typedef struct _GNUNET_OS_Process GNUNET_OS_Process;
 
+
 /**
  * Possible installation paths to request
  */
@@ -170,15 +175,93 @@
 #define GNUNET_OS_get_hostname_max_length() 255
 #endif
 
+/**
+ * Allocates new process structure
+ *
+ * Should be made internal?
+ *
+ * @return pointer to allocated structure
+ */
+GNUNET_OS_Process *GNUNET_OS_process_alloc ();
 
+
 /**
+ * Get process structure for current process
+ *
+ * The pointer it returns points to static memory location and must not be
+ * deallocated/closed
+ *
+ * @return pointer to the process sturcutre for this process
+ */
+GNUNET_OS_Process *GNUNET_OS_process_current ();
+
+
+/**
+ * Sends @sig to the process
+ *
+ * @param proc pointer to process structure
+ * @param sig signal
+ * @return 0 on success, -1 on error
+ */
+int GNUNET_OS_process_kill (GNUNET_OS_Process *proc, int sig);
+
+/**
+ * Get process ID
+ *
+ * Should be made internal?
+ *
+ * @param proc pointer to process structure
+ * @return process ID
+ */
+pid_t GNUNET_OS_process_get_pid (GNUNET_OS_Process *proc);
+
+/**
+ * Set process ID
+ *
+ * Should be made internal?
+ *
+ * @param proc pointer to process structure
+ * @param pid process ID
+ */
+void GNUNET_OS_process_set_pid (GNUNET_OS_Process *proc, pid_t pid);
+
+#if WINDOWS
+/**
+ * Get process handle
+ *
+ * Should be made internal?
+ *
+ * @param proc pointer to process structure
+ * @return process handle
+ */
+HANDLE GNUNET_OS_process_get_handle (GNUNET_OS_Process *proc);
+
+/**
+ * Set process handle
+ *
+ * Should be made internal?
+ *
+ * @param proc pointer to process structure
+ * @param handle process handle
+ */
+void GNUNET_OS_process_set_handle(GNUNET_OS_Process *proc, HANDLE handle);
+#endif
+
+/**
+ * Cleans up process structure contents (OS-dependent) and deallocates it
+ *
+ * @param proc pointer to process structure
+ */
+void GNUNET_OS_process_close (GNUNET_OS_Process *proc);
+
+/**
  * Set process priority
  *
- * @param proc id of the process
+ * @param proc pointer to process structure
  * @param prio priority value
  * @return GNUNET_OK on success, GNUNET_SYSERR on error
  */
-int GNUNET_OS_set_process_priority (pid_t proc,
+int GNUNET_OS_set_process_priority (GNUNET_OS_Process *proc,
                                     enum GNUNET_SCHEDULER_Priority prio);
 
 
@@ -189,9 +272,9 @@
  * @param pipe_stdout pipe to use to get output from child process (or NULL)
  * @param filename name of the binary
  * @param ... NULL-terminated list of arguments to the process
- * @return process ID of the new process, -1 on error
+ * @return pointer to process structure of the new process, NULL on error
  */
-pid_t
+GNUNET_OS_Process *
 GNUNET_OS_start_process (struct GNUNET_DISK_PipeHandle *pipe_stdin, 
 			 struct GNUNET_DISK_PipeHandle *pipe_stdout, 
 			 const char *filename, ...);
@@ -205,29 +288,30 @@
  * @param filename name of the binary
  * @param argv NULL-terminated list of arguments to the process,
  *             including the process name as the first argument
- * @return process ID of the new process, -1 on error
+ * @return pointer to process structure of the new process, NULL on error
  */
-pid_t GNUNET_OS_start_process_v (const int *lsocks,
-				 const char *filename, char *const argv[]);
+GNUNET_OS_Process *
+GNUNET_OS_start_process_v (const int *lsocks, const char *filename,
+			   char *const argv[]);
 
 
 /**
  * Retrieve the status of a process
- * @param proc process ID
+ * @param proc pointer to process structure
  * @param type status type
  * @param code return code/signal number
  * @return GNUNET_OK on success, GNUNET_NO if the process is still running, GNUNET_SYSERR otherwise
  */
-int GNUNET_OS_process_status (pid_t proc, enum GNUNET_OS_ProcessStatusType *type,
-    unsigned long *code);
+int GNUNET_OS_process_status (GNUNET_OS_Process *proc,
+    enum GNUNET_OS_ProcessStatusType *type, unsigned long *code);
 
 
 /**
  * Wait for a process
- * @param proc process ID to wait for
+ * @param proc pointer to process structure of the process to wait for
  * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
  */
-int GNUNET_OS_process_wait (pid_t proc);
+int GNUNET_OS_process_wait (GNUNET_OS_Process *proc);
 
 
 #if 0                           /* keep Emacsens' auto-indent happy */
Index: src/include/gnunet_testing_lib.h
===================================================================
--- src/include/gnunet_testing_lib.h	(revision 13533)
+++ src/include/gnunet_testing_lib.h	(working copy)
@@ -301,7 +301,7 @@
   /**
    * PID of the process that we started last.
    */
-  pid_t pid;
+  GNUNET_OS_Process *proc;
 
   /**
    * In which phase are we during the start of
Index: src/datastore/test_datastore_api_management.c
===================================================================
--- src/datastore/test_datastore_api_management.c	(revision 13533)
+++ src/datastore/test_datastore_api_management.c	(working copy)
@@ -350,7 +350,7 @@
 static int
 check ()
 {
-  pid_t pid;
+  GNUNET_OS_Process *proc;
   char cfg_name[128];
   char *const argv[] = { 
     "test-datastore-api-management",
@@ -368,7 +368,7 @@
 		   sizeof (cfg_name),
 		   "test_datastore_api_data_%s.conf",
 		   plugin_name);
-  pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                  "gnunet-service-arm",
 #if VERBOSE
                                  "-L", "DEBUG",
@@ -377,12 +377,14 @@
   GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
                       argv, "test-datastore-api", "nohelp",
                       options, &run, NULL);
-  if (0 != PLIBC_KILL (pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (proc, SIGTERM))
     {
       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
       ok = 1;
     }
-  GNUNET_OS_process_wait(pid);
+  GNUNET_OS_process_wait (proc);
+  GNUNET_OS_process_close (proc);
+  proc = NULL;
   if (ok != 0)
     fprintf (stderr, "Missed some testcases: %u\n", ok);
   return ok;
Index: src/datastore/test_datastore_api.c
===================================================================
--- src/datastore/test_datastore_api.c	(revision 13533)
+++ src/datastore/test_datastore_api.c	(working copy)
@@ -641,7 +641,7 @@
 {
   char cfg_name[128];
 #if START_DATASTORE
-  pid_t pid;
+  GNUNET_OS_Process *proc;
 #endif
   char *const argv[] = {
     "test-datastore-api",
@@ -660,7 +660,7 @@
 		   "test_datastore_api_data_%s.conf",
 		   plugin_name);
 #if START_DATASTORE
-  pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                  "gnunet-service-arm",
 #if VERBOSE
                                  "-L", "DEBUG",
@@ -671,12 +671,14 @@
                       argv, "test-datastore-api", "nohelp",
                       options, &run, NULL);
 #if START_DATASTORE
-  if (0 != PLIBC_KILL (pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (proc, SIGTERM))
     {
       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
       ok = 1;
     }
-  GNUNET_OS_process_wait(pid);
+  GNUNET_OS_process_wait (proc);
+  GNUNET_OS_process_close (proc);
+  proc = NULL;
 #endif
   if (ok != 0)
     fprintf (stderr, "Missed some testcases: %u\n", ok);
Index: src/datastore/perf_datastore_api.c
===================================================================
--- src/datastore/perf_datastore_api.c	(revision 13533)
+++ src/datastore/perf_datastore_api.c	(working copy)
@@ -372,7 +372,7 @@
 static int
 check ()
 {
-  pid_t pid;
+  GNUNET_OS_Process *proc;
   char cfg_name[128];
   char *const argv[] = { 
     "perf-datastore-api",
@@ -391,7 +391,7 @@
 		   sizeof (cfg_name),
 		   "test_datastore_api_data_%s.conf",
 		   plugin_name);
-  pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                  "gnunet-service-arm",
 #if VERBOSE
                                  "-L", "DEBUG",
@@ -400,12 +400,14 @@
   GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
                       argv, "perf-datastore-api", "nohelp",
                       options, &run, NULL);
-  if (0 != PLIBC_KILL (pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (proc, SIGTERM))
     {
       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
       ok = 1;
     }
-  GNUNET_OS_process_wait(pid);
+  GNUNET_OS_process_wait (proc);
+  GNUNET_OS_process_close (proc);
+  proc = NULL;
   return ok;
 }
 
Index: src/core/test_core_api_start_only.c
===================================================================
--- src/core/test_core_api_start_only.c	(revision 13533)
+++ src/core/test_core_api_start_only.c	(working copy)
@@ -49,7 +49,7 @@
   struct GNUNET_CORE_Handle *ch;
   struct GNUNET_PeerIdentity id;
 #if START_ARM
-  pid_t arm_pid;
+  GNUNET_OS_Process *arm_proc;
 #endif
 };
 
@@ -153,7 +153,7 @@
 {
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                         "gnunet-service-arm",
 #if VERBOSE
                                         "-L", "DEBUG",
@@ -193,12 +193,14 @@
 stop_arm (struct PeerContext *p)
 {
 #if START_ARM
-  if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  if (GNUNET_OS_process_wait(p->arm_pid) != GNUNET_OK)
+  if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK)
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "ARM process %u stopped\n", p->arm_pid);
+              "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc));
+  GNUNET_OS_process_close (p->arm_proc);
+  p->arm_proc = NULL;
 #endif
   GNUNET_CONFIGURATION_destroy (p->cfg);
 }
Index: src/core/test_core_api.c
===================================================================
--- src/core/test_core_api.c	(revision 13533)
+++ src/core/test_core_api.c	(working copy)
@@ -54,7 +54,7 @@
   struct GNUNET_MessageHeader *hello;
   int connect_status;
 #if START_ARM
-  pid_t arm_pid;
+  GNUNET_OS_Process *arm_proc;
 #endif
 };
 
@@ -289,7 +289,7 @@
 {
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                         "gnunet-service-arm",
 #if VERBOSE
                                         "-L", "DEBUG",
@@ -332,12 +332,14 @@
 stop_arm (struct PeerContext *p)
 {
 #if START_ARM
-  if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  if (GNUNET_OS_process_wait(p->arm_pid) != GNUNET_OK)
+  if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK)
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "ARM process %u stopped\n", p->arm_pid);
+              "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_pid));
+  GNUNET_OS_process_close (p->arm_proc);
+  p->arm_proc = NULL;
 #endif
   GNUNET_CONFIGURATION_destroy (p->cfg);
 }
Index: src/core/test_core_api_reliability.c
===================================================================
--- src/core/test_core_api_reliability.c	(revision 13533)
+++ src/core/test_core_api_reliability.c	(working copy)
@@ -74,7 +74,7 @@
   struct GNUNET_MessageHeader *hello;
   int connect_status;
 #if START_ARM
-  pid_t arm_pid;
+  GNUNET_OS_Process *arm_proc;
 #endif
 };
 
@@ -436,7 +436,7 @@
 {
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                         "gnunet-service-arm",
 #if VERBOSE
                                         "-L", "DEBUG",
@@ -479,12 +479,14 @@
 stop_arm (struct PeerContext *p)
 {
 #if START_ARM
-  if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  if (GNUNET_OS_process_wait(p->arm_pid) != GNUNET_OK)
+  if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK)
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "ARM process %u stopped\n", p->arm_pid);
+              "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc));
+  GNUNET_OS_process_close (p->arm_proc);
+  p->arm_proc = NULL;
 #endif
   GNUNET_CONFIGURATION_destroy (p->cfg);
 }
Index: src/core/test_core_quota_compliance.c
===================================================================
--- src/core/test_core_quota_compliance.c	(revision 13533)
+++ src/core/test_core_quota_compliance.c	(working copy)
@@ -472,7 +472,7 @@
 {
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                         "gnunet-service-arm",
 #if VERBOSE
                                         "-L", "DEBUG",
@@ -515,10 +515,12 @@
 stop_arm (struct PeerContext *p)
 {
 #if START_ARM
-  if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
   if (GNUNET_OS_process_wait(p->arm_pid) != GNUNET_OK)
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
+  GNUNET_OS_process_close (p->arm_proc);
+  p->arm_proc = NULL;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "ARM process %u stopped\n", p->arm_pid);
 #endif
Index: src/statistics/test_statistics_api.c
===================================================================
--- src/statistics/test_statistics_api.c	(revision 13533)
+++ src/statistics/test_statistics_api.c	(working copy)
@@ -29,7 +29,7 @@
 #include "gnunet_scheduler_lib.h"
 #include "gnunet_statistics_service.h"
 
-#define DEBUG_STATISTICS GNUNET_NO
+#define DEBUG_STATISTICS GNUNET_YES
 
 #define START_SERVICE GNUNET_YES
 
@@ -157,8 +157,8 @@
     GNUNET_GETOPT_OPTION_END
   };
 #if START_SERVICE
-  pid_t pid;
-  pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-statistics",
+  GNUNET_OS_Process *proc;
+  proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-statistics",
                                  "gnunet-service-statistics",
 #if DEBUG_STATISTICS
                                  "-L", "DEBUG",
@@ -168,19 +168,21 @@
   GNUNET_PROGRAM_run (5, argv, "test-statistics-api", "nohelp",
                       options, &run, &ok);
 #if START_SERVICE
-  if (0 != PLIBC_KILL (pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (proc, SIGTERM))
     {
       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
       ok = 1;
     }
-  GNUNET_OS_process_wait(pid);
+  GNUNET_OS_process_wait (proc);
+  GNUNET_OS_process_close (proc);
+  proc = NULL;
 #endif
   if (ok != 0)
     return ok;
   ok = 1;
 #if START_SERVICE
   /* restart to check persistence! */
-  pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-statistics",
+  proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-statistics",
                                  "gnunet-service-statistics",
 #if DEBUG_STATISTICS
                                  "-L", "DEBUG",
@@ -190,12 +192,14 @@
   GNUNET_PROGRAM_run (5, argv, "test-statistics-api", "nohelp",
                       options, &run_more, &ok);
 #if START_SERVICE
-  if (0 != PLIBC_KILL (pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (proc, SIGTERM))
     {
       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
       ok = 1;
     }
-  GNUNET_OS_process_wait(pid);
+  GNUNET_OS_process_wait (proc);
+  GNUNET_OS_process_close (proc);
+  proc = NULL;
 #endif
   return ok;
 }
Index: src/statistics/test_statistics_api_loop.c
===================================================================
--- src/statistics/test_statistics_api_loop.c	(revision 13533)
+++ src/statistics/test_statistics_api_loop.c	(working copy)
@@ -96,8 +96,8 @@
     GNUNET_GETOPT_OPTION_END
   };
 #if START_SERVICE
-  pid_t pid;
-  pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-statistics",
+  GNUNET_OS_Process *proc;
+  proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-statistics",
                                  "gnunet-service-statistics",
 #if DEBUG_STATISTICS
                                  "-L", "DEBUG",
@@ -107,12 +107,14 @@
   GNUNET_PROGRAM_run (3, argv, "test-statistics-api", "nohelp",
                       options, &run, &ok);
 #if START_SERVICE
-  if (0 != PLIBC_KILL (pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (proc, SIGTERM))
     {
       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
       ok = 1;
     }
-  GNUNET_OS_process_wait(pid);
+  GNUNET_OS_process_wait (proc);
+  GNUNET_OS_process_close (proc);
+  proc = NULL;
 #endif
   return ok;
 }
Index: src/transport/plugin_transport_udp.c
===================================================================
--- src/transport/plugin_transport_udp.c	(revision 13533)
+++ src/transport/plugin_transport_udp.c	(working copy)
@@ -471,7 +471,7 @@
   /**
    * The process id of the server process (if behind NAT)
    */
-  pid_t server_pid;
+  GNUNET_OS_Process *server_proc;
 
 };
 
@@ -528,9 +528,11 @@
     }
   if (plugin->behind_nat == GNUNET_YES)
     {
-      if (0 != PLIBC_KILL (plugin->server_pid, SIGTERM))
+      if (0 != GNUNET_OS_process_kill (plugin->server_proc, SIGTERM))
 	GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-      GNUNET_OS_process_wait (plugin->server_pid);
+      GNUNET_OS_process_wait (plugin->server_proc);
+      GNUNET_OS_process_close (plugin->server_proc);
+      plugin->server_proc = NULL;
     }
   return GNUNET_OK;
 }
@@ -700,7 +702,7 @@
   char addr_buf[INET_ADDRSTRLEN];
   char *address_as_string;
   char *port_as_string;
-  pid_t pid;
+  GNUNET_OS_Process *proc;
   const struct IPv4UdpAddress *t4;
 
   GNUNET_assert(addrlen == sizeof(struct IPv4UdpAddress));
@@ -721,10 +723,12 @@
 #endif
 
   /* Start the server process */
-  pid = GNUNET_OS_start_process(NULL, NULL, "gnunet-nat-client", "gnunet-nat-client", plugin->external_address, address_as_string, port_as_string, NULL);
+  proc = GNUNET_OS_start_process(NULL, NULL, "gnunet-nat-client", "gnunet-nat-client", plugin->external_address, address_as_string, port_as_string, NULL);
   GNUNET_free(address_as_string);
   GNUNET_free(port_as_string);
-  GNUNET_OS_process_wait (pid);
+  GNUNET_OS_process_wait (proc);
+  GNUNET_OS_process_close (proc);
+  proc = NULL;
 }
 
 /**
@@ -1637,12 +1641,12 @@
                   plugin->internal_address);
 #endif
       /* Start the server process */
-      plugin->server_pid = GNUNET_OS_start_process(NULL,
+      plugin->server_proc = GNUNET_OS_start_process(NULL,
 						   plugin->server_stdout,
 						   "gnunet-nat-server",
 						   "gnunet-nat-server",
 						   plugin->internal_address, NULL);
-      if (plugin->server_pid == GNUNET_SYSERR)
+      if (plugin->server_proc == NULL)
         {
 #if DEBUG_UDP
           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
Index: src/transport/test_quota_compliance.c
===================================================================
--- src/transport/test_quota_compliance.c	(revision 13533)
+++ src/transport/test_quota_compliance.c	(working copy)
@@ -65,7 +65,7 @@
   struct GNUNET_TRANSPORT_Handle *th;
   struct GNUNET_PeerIdentity id;
 #if START_ARM
-  pid_t arm_pid;
+  GNUNET_OS_Process *arm_proc;
 #endif
 };
 
@@ -197,9 +197,11 @@
 stop_arm (struct PeerContext *p)
 {
 #if START_ARM
-  if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  GNUNET_OS_process_wait (p->arm_pid);
+  GNUNET_OS_process_wait (p->arm_proc);
+  GNUNET_OS_process_close (p->arm_proc);
+  p->arm_proc = NULL;
 #endif
   GNUNET_CONFIGURATION_destroy (p->cfg);
 }
@@ -572,7 +574,7 @@
 {
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL,
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL,
 					"gnunet-service-arm",
                                         "gnunet-service-arm",
 #if VERBOSE_ARM
Index: src/transport/plugin_transport_tcp.c
===================================================================
--- src/transport/plugin_transport_tcp.c	(revision 13533)
+++ src/transport/plugin_transport_tcp.c	(working copy)
@@ -345,7 +345,7 @@
   /**
    * The process id of the server process (if behind NAT)
    */
-  pid_t server_pid;
+  GNUNET_OS_Process *server_proc;
 
   /**
    * List of open TCP sessions.
@@ -958,7 +958,7 @@
   char inet4[INET_ADDRSTRLEN];
   char *address_as_string;
   char *port_as_string;
-  pid_t pid;
+  GNUNET_OS_Process *proc;
   const struct sockaddr *sa = (const struct sockaddr *)addr;
 
 #if DEBUG_TCP_NAT
@@ -995,10 +995,12 @@
 #endif
 
   /* Start the client process */
-  pid = GNUNET_OS_start_process(NULL, NULL, "gnunet-nat-client", "gnunet-nat-client", plugin->external_address, address_as_string, port_as_string, NULL);
+  proc = GNUNET_OS_start_process(NULL, NULL, "gnunet-nat-client", "gnunet-nat-client", plugin->external_address, address_as_string, port_as_string, NULL);
   GNUNET_free(address_as_string);
   GNUNET_free(port_as_string);
-  GNUNET_OS_process_wait (pid);
+  GNUNET_OS_process_wait (proc);
+  GNUNET_OS_process_close (proc);
+  proc = NULL;
 }
 
 
@@ -2201,8 +2203,8 @@
                    "Starting gnunet-nat-server process cmd: %s %s\n", "gnunet-nat-server", plugin->internal_address);
 #endif
   /* Start the server process */
-  plugin->server_pid = GNUNET_OS_start_process(NULL, plugin->server_stdout, "gnunet-nat-server", "gnunet-nat-server", plugin->internal_address, NULL);
-  if (plugin->server_pid == GNUNET_SYSERR)
+  plugin->server_proc = GNUNET_OS_start_process(NULL, plugin->server_stdout, "gnunet-nat-server", "gnunet-nat-server", plugin->internal_address, NULL);
+  if (plugin->server_proc == NULL)
     {
 #if DEBUG_TCP_NAT
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2603,9 +2605,11 @@
 
   if (plugin->behind_nat == GNUNET_YES)
     {
-      if (0 != PLIBC_KILL (plugin->server_pid, SIGTERM))
+      if (0 != GNUNET_OS_process_kill (plugin->server_proc, SIGTERM))
         GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-      GNUNET_OS_process_wait (plugin->server_pid);
+      GNUNET_OS_process_wait (plugin->server_proc);
+      GNUNET_OS_process_close (plugin->server_proc);
+      plugin->server_proc = NULL;
     }
   GNUNET_free_non_null(plugin->bind_address);
   GNUNET_free (plugin);
Index: src/transport/test_transport_api.c
===================================================================
--- src/transport/test_transport_api.c	(revision 13533)
+++ src/transport/test_transport_api.c	(working copy)
@@ -60,7 +60,7 @@
   struct GNUNET_TRANSPORT_Handle *th;
   struct GNUNET_PeerIdentity id;
 #if START_ARM
-  pid_t arm_pid;
+  GNUNET_OS_Process *arm_proc;
 #endif
 };
 
@@ -118,9 +118,11 @@
 stop_arm (struct PeerContext *p)
 {
 #if START_ARM
-  if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  GNUNET_OS_process_wait (p->arm_pid);
+  GNUNET_OS_process_wait (p->arm_proc);
+  GNUNET_OS_process_close (p->arm_proc);
+  p->arm_proc = NULL;
 #endif
   GNUNET_CONFIGURATION_destroy (p->cfg);
 }
@@ -220,7 +222,7 @@
 {
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                         "gnunet-service-arm",
 #if VERBOSE_ARM
                                         "-L", "DEBUG",
Index: src/transport/test_transport_api_reliability.c
===================================================================
--- src/transport/test_transport_api_reliability.c	(revision 13533)
+++ src/transport/test_transport_api_reliability.c	(working copy)
@@ -62,7 +62,7 @@
   struct GNUNET_TRANSPORT_Handle *th;
   struct GNUNET_PeerIdentity id;
 #if START_ARM
-  pid_t arm_pid;
+  GNUNET_OS_Process *arm_proc;
 #endif
 };
 
@@ -141,9 +141,11 @@
 stop_arm (struct PeerContext *p)
 {
 #if START_ARM
-  if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  GNUNET_OS_process_wait (p->arm_pid);
+  GNUNET_OS_process_wait (p->arm_proc);
+  GNUNET_OS_process_close (p->arm_proc);
+  p->arm_proc = NULL;
 #endif
   GNUNET_CONFIGURATION_destroy (p->cfg);
 }
@@ -381,7 +383,7 @@
 {
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL,
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL,
 					"gnunet-service-arm",
                                         "gnunet-service-arm",
 #if VERBOSE_ARM
Index: src/transport/plugin_transport_wlan.c
===================================================================
--- src/transport/plugin_transport_wlan.c	(revision 13533)
+++ src/transport/plugin_transport_wlan.c	(working copy)
@@ -135,7 +135,7 @@
   /**
    * The process id of the server process (if behind NAT)
    */
-  pid_t server_pid;
+  GNUNET_OS_Process *server_proc;
 
   /**
    * The interface of the wlan card given to us by the user.
@@ -1245,8 +1245,8 @@
                    "Starting gnunet-wlan-helper process cmd: %s %s\n", "gnunet-wlan-helper", plugin->interface);
 #endif
   /* Start the server process */
-  plugin->server_pid = GNUNET_OS_start_process(plugin->server_stdin, plugin->server_stdout, "gnunet-transport-wlan-helper", "gnunet-transport-wlan-helper", plugin->interface, NULL);
-  if (plugin->server_pid == GNUNET_SYSERR)
+  plugin->server_proc = GNUNET_OS_start_process(plugin->server_stdin, plugin->server_stdout, "gnunet-transport-wlan-helper", "gnunet-transport-wlan-helper", plugin->interface, NULL);
+  if (plugin->server_proc == NULL)
     {
 #if DEBUG_TCP_NAT
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
Index: src/monkey/test_gnunet_monkey.c
===================================================================
--- src/monkey/test_gnunet_monkey.c	(revision 13533)
+++ src/monkey/test_gnunet_monkey.c	(working copy)
@@ -42,9 +42,12 @@
 static int
 check ()
 {
-    GNUNET_OS_start_process (NULL, NULL, "gnunet-monkey",
-	                                     "gnunet-monkey",
-	                                     "./bug_null_pointer_exception", NULL);
+    GNUNET_OS_process_close (GNUNET_OS_start_process (NULL, NULL,
+    			                              "gnunet-monkey",
+	                                              "gnunet-monkey",
+	                                        "./bug_null_pointer_exception",
+                                                      NULL));
+    
 	return 0;
 }
 
Index: src/vpn/gnunet-daemon-vpn.c
===================================================================
--- src/vpn/gnunet-daemon-vpn.c	(revision 13533)
+++ src/vpn/gnunet-daemon-vpn.c	(working copy)
@@ -94,7 +94,7 @@
 /**
  * The process id of the helper
  */
-static pid_t helper_pid;
+static GNUNET_OS_Process *helper_proc;
 
 /**
  * a list of outgoing dns-query-packets
@@ -177,8 +177,10 @@
     GNUNET_assert (0 != (tskctx->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN));
 
     /* stop the helper */
-    PLIBC_KILL(helper_pid, SIGTERM);
-    GNUNET_OS_process_wait(helper_pid);
+    GNUNET_OS_process_kill (helper_proc, SIGTERM);
+    GNUNET_OS_process_wait (helper_proc);
+    GNUNET_OS_process_close (helper_proc);
+    helper_proc = NULL;
 
     /* close the connection to the service-dns */
     if (dns_connection != NULL)
@@ -202,7 +204,7 @@
 
     if (helper_in == NULL || helper_out == NULL) return;
 
-    helper_pid = GNUNET_OS_start_process(helper_in, helper_out, "gnunet-helper-vpn", "gnunet-helper-vpn", NULL);
+    helper_proc = GNUNET_OS_start_process(helper_in, helper_out, "gnunet-helper-vpn", "gnunet-helper-vpn", NULL);
 
     fh_from_helper = GNUNET_DISK_pipe_handle (helper_out, GNUNET_DISK_PIPE_END_READ);
     fh_to_helper = GNUNET_DISK_pipe_handle (helper_in, GNUNET_DISK_PIPE_END_WRITE);
@@ -219,8 +221,10 @@
 static void
 restart_helper(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tskctx) {
     // Kill the helper
-    PLIBC_KILL(helper_pid, SIGKILL);
-    GNUNET_OS_process_wait(helper_pid);
+    GNUNET_OS_process_kill (helper_proc, SIGKILL);
+    GNUNET_OS_process_wait (helper_proc);
+    GNUNET_OS_process_close (helper_proc);
+    helper_proc = NULL;
 
     /* Tell the dns-service to rehijack the dns-port
      * The routing-table gets flushed if an interface disappears.
Index: src/vpn/gnunet-service-dns.c
===================================================================
--- src/vpn/gnunet-service-dns.c	(revision 13533)
+++ src/vpn/gnunet-service-dns.c	(working copy)
@@ -112,12 +112,12 @@
 
     GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Hijacking, port is %d\n", port);
     snprintf(port_s, 6, "%d", port);
-    GNUNET_OS_start_process(NULL,
+    GNUNET_OS_process_close (GNUNET_OS_start_process(NULL,
 			    NULL,
 			    "gnunet-helper-hijack-dns",
 			    "gnunet-hijack-dns",
 			    port_s,
-			    NULL);
+			    NULL));
 }
 
 /**
Index: src/peerinfo/test_peerinfo_api.c
===================================================================
--- src/peerinfo/test_peerinfo_api.c	(revision 13533)
+++ src/peerinfo/test_peerinfo_api.c	(working copy)
@@ -165,7 +165,7 @@
 check ()
 {
   int ok = 3;
-  pid_t pid;
+  GNUNET_OS_Process *proc;
   char *const argv[] = { "test-peerinfo-api",
     "-c",
     "test_peerinfo_api_data.conf",
@@ -177,7 +177,7 @@
   struct GNUNET_GETOPT_CommandLineOption options[] = {
     GNUNET_GETOPT_OPTION_END
   };
-  pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-peerinfo",
+  proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-peerinfo",
                                  "gnunet-service-peerinfo",
 #if DEBUG_PEERINFO
                                  "-L", "DEBUG",
@@ -186,12 +186,14 @@
   GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
                       argv, "test-peerinfo-api", "nohelp",
                       options, &run, &ok);
-  if (0 != PLIBC_KILL (pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (proc, SIGTERM))
     {
       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
       ok = 1;
     }
-  GNUNET_OS_process_wait(pid);
+  GNUNET_OS_process_wait (proc);
+  GNUNET_OS_process_close (proc);
+  proc = NULL;
   return ok;
 }
 
Index: src/peerinfo/perf_peerinfo_api.c
===================================================================
--- src/peerinfo/perf_peerinfo_api.c	(revision 13533)
+++ src/peerinfo/perf_peerinfo_api.c	(working copy)
@@ -166,11 +166,11 @@
     NULL
   };
 #if START_SERVICE
-  pid_t pid;
+  GNUNET_OS_Process *proc;
   struct GNUNET_GETOPT_CommandLineOption options[] = {
     GNUNET_GETOPT_OPTION_END
   };
-  pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-peerinfo",
+  proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-peerinfo",
                                  "gnunet-service-peerinfo",
 #if DEBUG_PEERINFO
                                  "-L", "DEBUG",
@@ -185,12 +185,15 @@
 	   numpeers,
 	   NUM_REQUESTS * NUM_REQUESTS / 2);
 #if START_SERVICE
-  if (0 != PLIBC_KILL (pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (proc, SIGTERM))
     {
       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
       ok = 1;
     }
-  GNUNET_OS_process_wait(pid);
+  GNUNET_OS_process_wait (proc);
+  GNUNET_OS_process_close (proc);
+  proc = NULL;
+
 #endif
   return ok;
 }
Index: src/fs/test_fs_unindex_persistence.c
===================================================================
--- src/fs/test_fs_unindex_persistence.c	(revision 13533)
+++ src/fs/test_fs_unindex_persistence.c	(working copy)
@@ -51,7 +51,7 @@
 {
   struct GNUNET_CONFIGURATION_Handle *cfg;
 #if START_ARM
-  pid_t arm_pid;
+  GNUNET_OS_Process *arm_proc;
 #endif
 };
 
@@ -266,7 +266,7 @@
 {
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                         "gnunet-service-arm",
 #if VERBOSE
                                         "-L", "DEBUG",
@@ -281,12 +281,14 @@
 stop_arm (struct PeerContext *p)
 {
 #if START_ARM
-  if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  if (GNUNET_OS_process_wait(p->arm_pid) != GNUNET_OK)
+  if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK)
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "ARM process %u stopped\n", p->arm_pid);
+              "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc));
+  GNUNET_OS_process_close (p->arm_proc);
+  p->arm_proc = NULL;
 #endif
   GNUNET_CONFIGURATION_destroy (p->cfg);
 }
Index: src/fs/test_fs_start_stop.c
===================================================================
--- src/fs/test_fs_start_stop.c	(revision 13533)
+++ src/fs/test_fs_start_stop.c	(working copy)
@@ -41,7 +41,7 @@
 {
   struct GNUNET_CONFIGURATION_Handle *cfg;
 #if START_ARM
-  pid_t arm_pid;
+  GNUNET_OS_Process *arm_proc;
 #endif
 };
 
@@ -59,7 +59,7 @@
 {
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                         "gnunet-service-arm",
 #if VERBOSE
                                         "-L", "DEBUG",
@@ -74,12 +74,14 @@
 stop_arm (struct PeerContext *p)
 {
 #if START_ARM
-  if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  if (GNUNET_OS_process_wait(p->arm_pid) != GNUNET_OK)
+  if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK)
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "ARM process %u stopped\n", p->arm_pid);
+              "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc));
+  GNUNET_OS_process_close (p->arm_proc);
+  p->arm_proc = NULL;
 #endif
   GNUNET_CONFIGURATION_destroy (p->cfg);
 }
Index: src/fs/test_fs_publish.c
===================================================================
--- src/fs/test_fs_publish.c	(revision 13533)
+++ src/fs/test_fs_publish.c	(working copy)
@@ -53,7 +53,7 @@
 {
   struct GNUNET_CONFIGURATION_Handle *cfg;
 #if START_ARM
-  pid_t arm_pid;
+  GNUNET_OS_Process *arm_proc;
 #endif
 };
 
@@ -184,7 +184,7 @@
 {
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                         "gnunet-service-arm",
 #if VERBOSE
                                         "-L", "DEBUG",
@@ -199,12 +199,14 @@
 stop_arm (struct PeerContext *p)
 {
 #if START_ARM
-  if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  if (GNUNET_OS_process_wait(p->arm_pid) != GNUNET_OK)
+  if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK)
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "ARM process %u stopped\n", p->arm_pid);
+              "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc));
+  GNUNET_OS_process_close (p->arm_proc);
+  p->arm_proc = NULL;
 #endif
   GNUNET_CONFIGURATION_destroy (p->cfg);
 }
Index: src/fs/test_fs_search_persistence.c
===================================================================
--- src/fs/test_fs_search_persistence.c	(revision 13533)
+++ src/fs/test_fs_search_persistence.c	(working copy)
@@ -53,7 +53,7 @@
   struct GNUNET_CONFIGURATION_Handle *cfg;
   struct GNUNET_PeerIdentity id;   
 #if START_ARM
-  pid_t arm_pid;
+  GNUNET_OS_Process *arm_proc;
 #endif
 };
 
@@ -262,7 +262,7 @@
 {
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                         "gnunet-service-arm",
 #if VERBOSE
                                         "-L", "DEBUG",
@@ -277,12 +277,14 @@
 stop_arm (struct PeerContext *p)
 {
 #if START_ARM
-  if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  if (GNUNET_OS_process_wait(p->arm_pid) != GNUNET_OK)
+  if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK)
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "ARM process %u stopped\n", p->arm_pid);
+              "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc));
+  GNUNET_OS_process_close (p->arm_proc);
+  p->arm_proc = NULL;
 #endif
   GNUNET_CONFIGURATION_destroy (p->cfg);
 }
Index: src/fs/test_fs_download_persistence.c
===================================================================
--- src/fs/test_fs_download_persistence.c	(revision 13533)
+++ src/fs/test_fs_download_persistence.c	(working copy)
@@ -52,7 +52,7 @@
 {
   struct GNUNET_CONFIGURATION_Handle *cfg;
 #if START_ARM
-  pid_t arm_pid;
+  GNUNET_OS_Process *arm_proc;
 #endif
 };
 
@@ -310,7 +310,7 @@
 {
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                         "gnunet-service-arm",
 #if VERBOSE
                                         "-L", "DEBUG",
@@ -325,12 +325,14 @@
 stop_arm (struct PeerContext *p)
 {
 #if START_ARM
-  if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  if (GNUNET_OS_process_wait(p->arm_pid) != GNUNET_OK)
+  if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK)
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "ARM process %u stopped\n", p->arm_pid);
+              "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc));
+  GNUNET_OS_process_close (p->arm_proc);
+  p->arm_proc = NULL;
 #endif
   GNUNET_CONFIGURATION_destroy (p->cfg);
 }
Index: src/fs/test_fs_namespace.c
===================================================================
--- src/fs/test_fs_namespace.c	(revision 13533)
+++ src/fs/test_fs_namespace.c	(working copy)
@@ -59,7 +59,7 @@
 {
   struct GNUNET_CONFIGURATION_Handle *cfg;
 #if START_ARM
-  pid_t arm_pid;
+  GNUNET_OS_Process *arm_proc;
 #endif
 };
 
@@ -69,7 +69,7 @@
 {
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                         "gnunet-service-arm",
 #if VERBOSE
                                         "-L", "DEBUG",
@@ -84,12 +84,14 @@
 stop_arm (struct PeerContext *p)
 {
 #if START_ARM
-  if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  if (GNUNET_OS_process_wait(p->arm_pid) != GNUNET_OK)
+  if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK)
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "ARM process %u stopped\n", p->arm_pid);
+              "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc));
+  GNUNET_OS_process_close (p->arm_proc);
+  p->arm_proc = NULL;
 #endif
   GNUNET_CONFIGURATION_destroy (p->cfg);
 }
Index: src/fs/test_fs_download_indexed.c
===================================================================
--- src/fs/test_fs_download_indexed.c	(revision 13533)
+++ src/fs/test_fs_download_indexed.c	(working copy)
@@ -52,7 +52,7 @@
 {
   struct GNUNET_CONFIGURATION_Handle *cfg;
 #if START_ARM
-  pid_t arm_pid;
+  GNUNET_OS_Process *arm_proc;
 #endif
 };
 
@@ -251,7 +251,7 @@
 {
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                         "gnunet-service-arm",
 #if VERBOSE
                                         "-L", "DEBUG",
@@ -266,12 +266,14 @@
 stop_arm (struct PeerContext *p)
 {
 #if START_ARM
-  if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  if (GNUNET_OS_process_wait(p->arm_pid) != GNUNET_OK)
+  if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK)
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "ARM process %u stopped\n", p->arm_pid);
+              "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc));
+  GNUNET_OS_process_close (p->arm_proc);
+  p->arm_proc = NULL;
 #endif
   GNUNET_CONFIGURATION_destroy (p->cfg);
 }
Index: src/fs/test_fs_unindex.c
===================================================================
--- src/fs/test_fs_unindex.c	(revision 13533)
+++ src/fs/test_fs_unindex.c	(working copy)
@@ -52,7 +52,7 @@
 {
   struct GNUNET_CONFIGURATION_Handle *cfg;
 #if START_ARM
-  pid_t arm_pid;
+  GNUNET_OS_Process *arm_proc;
 #endif
 };
 
@@ -196,7 +196,7 @@
 {
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                         "gnunet-service-arm",
 #if VERBOSE
                                         "-L", "DEBUG",
@@ -211,12 +211,14 @@
 stop_arm (struct PeerContext *p)
 {
 #if START_ARM
-  if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  if (GNUNET_OS_process_wait(p->arm_pid) != GNUNET_OK)
+  if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK)
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "ARM process %u stopped\n", p->arm_pid);
+              "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc));
+  GNUNET_OS_process_close (p->arm_proc);
+  p->arm_proc = NULL;
 #endif
   GNUNET_CONFIGURATION_destroy (p->cfg);
 }
Index: src/fs/test_fs_list_indexed.c
===================================================================
--- src/fs/test_fs_list_indexed.c	(revision 13533)
+++ src/fs/test_fs_list_indexed.c	(working copy)
@@ -56,7 +56,7 @@
 {
   struct GNUNET_CONFIGURATION_Handle *cfg;
 #if START_ARM
-  pid_t arm_pid;
+  GNUNET_OS_Process *arm_proc;
 #endif
 };
 
@@ -199,7 +199,7 @@
 {
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                         "gnunet-service-arm",
 #if VERBOSE
                                         "-L", "DEBUG",
@@ -214,12 +214,14 @@
 stop_arm (struct PeerContext *p)
 {
 #if START_ARM
-  if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  if (GNUNET_OS_process_wait(p->arm_pid) != GNUNET_OK)
+  if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK)
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "ARM process %u stopped\n", p->arm_pid);
+              "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc));
+  GNUNET_OS_process_close (p->arm_proc);
+  p->arm_proc = NULL;
 #endif
   GNUNET_CONFIGURATION_destroy (p->cfg);
 }
Index: src/fs/test_fs_namespace_list_updateable.c
===================================================================
--- src/fs/test_fs_namespace_list_updateable.c	(revision 13533)
+++ src/fs/test_fs_namespace_list_updateable.c	(working copy)
@@ -55,7 +55,7 @@
 {
   struct GNUNET_CONFIGURATION_Handle *cfg;
 #if START_ARM
-  pid_t arm_pid;
+  GNUNET_OS_Process *arm_proc;
 #endif
 };
 
@@ -73,7 +73,7 @@
 {
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                         "gnunet-service-arm",
 #if VERBOSE
                                         "-L", "DEBUG",
@@ -88,12 +88,14 @@
 stop_arm (struct PeerContext *p)
 {
 #if START_ARM
-  if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  if (GNUNET_OS_process_wait(p->arm_pid) != GNUNET_OK)
+  if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK)
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "ARM process %u stopped\n", p->arm_pid);
+              "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc));
+  GNUNET_OS_process_close (p->arm_proc);
+  p->arm_proc = NULL;
 #endif
   if (uri_this != NULL)
     GNUNET_FS_uri_destroy (uri_this);
Index: src/fs/test_fs_search_ranking.c
===================================================================
--- src/fs/test_fs_search_ranking.c	(revision 13533)
+++ src/fs/test_fs_search_ranking.c	(working copy)
@@ -126,7 +126,7 @@
 main (int argc, char *argv[])
 {
 #if START_DAEMON
-  pid_t daemon;
+  GNUNET_OS_Process *daemon;
 #endif
   int ok;
   char *fn = NULL;
@@ -153,7 +153,7 @@
 #if START_DAEMON
   GNUNET_disk_directory_remove (NULL, "/tmp/gnunet-fsui-searchranktest/");
   daemon = GNUNET_daemon_start (NULL, cfg, "peer.conf", GNUNET_NO);
-  GNUNET_GE_ASSERT (NULL, daemon > 0);
+  GNUNET_GE_ASSERT (NULL, daemon != NULL);
   CHECK (GNUNET_OK ==
          GNUNET_wait_for_daemon_running (NULL, cfg,
                                          30 * GNUNET_CRON_SECONDS));
@@ -242,6 +242,8 @@
 
 #if START_DAEMON
   GNUNET_GE_ASSERT (NULL, GNUNET_OK == GNUNET_daemon_stop (NULL, daemon));
+  GNUNET_OS_process_close (daemon);
+  daemon = NULL;
 #endif
   GNUNET_GC_free (cfg);
   return (ok == GNUNET_YES) ? 0 : 1;
Index: src/fs/test_fs_download_recursive.c
===================================================================
--- src/fs/test_fs_download_recursive.c	(revision 13533)
+++ src/fs/test_fs_download_recursive.c	(working copy)
@@ -29,7 +29,7 @@
 #include "gnunet_util.h"
 #include "gnunet_fsui_lib.h"
 
-#define DEBUG_VERBOSE GNUNET_NO
+#define DEBUG_VERBOSE GNUNET_YES
 
 #define CHECK(a) if (!(a)) { ok = GNUNET_NO; GNUNET_GE_BREAK(ectx, 0); goto FAILURE; }
 
@@ -256,7 +256,7 @@
 main (int argc, char *argv[])
 {
 #if START_DAEMON
-  pid_t daemon;
+  GNUNET_OS_Process *daemon;
 #endif
   int ok;
   char *fn = NULL;
@@ -284,7 +284,7 @@
   GNUNET_disk_directory_remove (NULL,
                                 "/tmp/gnunet-fsui-recursive_download_test/");
   daemon = GNUNET_daemon_start (NULL, cfg, "peer.conf", GNUNET_NO);
-  GNUNET_GE_ASSERT (NULL, daemon > 0);
+  GNUNET_GE_ASSERT (NULL, daemon != NULL);
   CHECK (GNUNET_OK ==
          GNUNET_wait_for_daemon_running (NULL, cfg,
                                          30 * GNUNET_CRON_SECONDS));
@@ -372,6 +372,8 @@
 
 #if START_DAEMON
   GNUNET_GE_BREAK (NULL, GNUNET_OK == GNUNET_daemon_stop (NULL, daemon));
+  GNUNET_OS_process_close (daemon);
+  daemon = NULL;
 #endif
   GNUNET_GC_free (cfg);
   return (ok == GNUNET_YES) ? 0 : 1;
Index: src/fs/test_fs_search.c
===================================================================
--- src/fs/test_fs_search.c	(revision 13533)
+++ src/fs/test_fs_search.c	(working copy)
@@ -53,7 +53,7 @@
   struct GNUNET_CONFIGURATION_Handle *cfg;
   struct GNUNET_PeerIdentity id;   
 #if START_ARM
-  pid_t arm_pid;
+  GNUNET_OS_Process *arm_proc;
 #endif
 };
 
@@ -191,7 +191,7 @@
 {
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                         "gnunet-service-arm",
 #if VERBOSE
                                         "-L", "DEBUG",
@@ -206,12 +206,14 @@
 stop_arm (struct PeerContext *p)
 {
 #if START_ARM
-  if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  if (GNUNET_OS_process_wait(p->arm_pid) != GNUNET_OK)
+  if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK)
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "ARM process %u stopped\n", p->arm_pid);
+              "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc));
+  GNUNET_OS_process_close (p->arm_proc);
+  p->arm_proc = NULL;
 #endif
   GNUNET_CONFIGURATION_destroy (p->cfg);
 }
Index: src/fs/test_fs_download.c
===================================================================
--- src/fs/test_fs_download.c	(revision 13533)
+++ src/fs/test_fs_download.c	(working copy)
@@ -52,7 +52,7 @@
 {
   struct GNUNET_CONFIGURATION_Handle *cfg;
 #if START_ARM
-  pid_t arm_pid;
+  GNUNET_OS_Process *arm_proc;
 #endif
 };
 
@@ -249,7 +249,7 @@
 {
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                         "gnunet-service-arm",
 #if VERBOSE
                                         "-L", "DEBUG",
@@ -264,12 +264,14 @@
 stop_arm (struct PeerContext *p)
 {
 #if START_ARM
-  if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  if (GNUNET_OS_process_wait(p->arm_pid) != GNUNET_OK)
+  if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK)
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "ARM process %u stopped\n", p->arm_pid);
+              "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc));
+  GNUNET_OS_process_close (p->arm_proc);
+  p->arm_proc = NULL;
 #endif
   GNUNET_CONFIGURATION_destroy (p->cfg);
 }
Index: src/fs/test_fs_publish_persistence.c
===================================================================
--- src/fs/test_fs_publish_persistence.c	(revision 13533)
+++ src/fs/test_fs_publish_persistence.c	(working copy)
@@ -52,7 +52,7 @@
 {
   struct GNUNET_CONFIGURATION_Handle *cfg;
 #if START_ARM
-  pid_t arm_pid;
+  GNUNET_OS_Process *arm_proc;
 #endif
 };
 
@@ -243,7 +243,7 @@
 {
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                         "gnunet-service-arm",
 #if VERBOSE
                                         "-L", "DEBUG",
@@ -258,12 +258,14 @@
 stop_arm (struct PeerContext *p)
 {
 #if START_ARM
-  if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  if (GNUNET_OS_process_wait(p->arm_pid) != GNUNET_OK)
+  if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK)
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "ARM process %u stopped\n", p->arm_pid);
+              "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc));
+  GNUNET_OS_process_close (p->arm_proc);
+  p->arm_proc = NULL;
 #endif
   GNUNET_CONFIGURATION_destroy (p->cfg);
 }
Index: src/fs/test_fs.c
===================================================================
--- src/fs/test_fs.c	(revision 13533)
+++ src/fs/test_fs.c	(working copy)
@@ -104,7 +104,7 @@
 main (int argc, char *argv[])
 {
 #if START_DAEMON
-  pid_t daemon;
+  GNUNET_OS_Process *daemon;
 #endif
   int ok;
   struct GNUNET_ECRS_URI *uri;
@@ -132,7 +132,7 @@
     }
 #if START_DAEMON
   daemon = GNUNET_daemon_start (NULL, cfg, "peer.conf", GNUNET_NO);
-  GNUNET_GE_ASSERT (NULL, daemon > 0);
+  GNUNET_GE_ASSERT (NULL, daemon != NULL);
   CHECK (GNUNET_OK ==
          GNUNET_wait_for_daemon_running (NULL, cfg,
                                          60 * GNUNET_CRON_SECONDS));
@@ -250,6 +250,7 @@
 
 #if START_DAEMON
   GNUNET_GE_ASSERT (NULL, GNUNET_OK == GNUNET_daemon_stop (NULL, daemon));
+  GNUNET_OS_process_close (daemon);
 #endif
   GNUNET_GC_free (cfg);
 
Index: src/hostlist/test_gnunet_daemon_hostlist.c
===================================================================
--- src/hostlist/test_gnunet_daemon_hostlist.c	(revision 13533)
+++ src/hostlist/test_gnunet_daemon_hostlist.c	(working copy)
@@ -49,7 +49,7 @@
   struct GNUNET_TRANSPORT_Handle *th;
   struct GNUNET_MessageHeader *hello;
 #if START_ARM
-  pid_t arm_pid;
+  GNUNET_OS_Process *arm_proc;
 #endif
 };
 
@@ -135,7 +135,7 @@
 {
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                         "gnunet-service-arm",
 #if VERBOSE
                                         "-L", "DEBUG",
@@ -159,12 +159,14 @@
 #if START_ARM 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
 	      "Killing ARM process.\n");
-  if (0 != PLIBC_KILL (p->arm_pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  if (GNUNET_OS_process_wait(p->arm_pid) != GNUNET_OK)
+  if (GNUNET_OS_process_wait(p->arm_proc) != GNUNET_OK)
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "ARM process %u stopped\n", p->arm_pid);
+              "ARM process %u stopped\n", GNUNET_OS_process_get_pid (p->arm_proc));
+  GNUNET_OS_process_close (p->arm_proc);
+  p->arm_proc = NULL;
 #endif
   GNUNET_CONFIGURATION_destroy (p->cfg);
 }
Index: src/hostlist/test_gnunet_daemon_hostlist_learning.c
===================================================================
--- src/hostlist/test_gnunet_daemon_hostlist_learning.c	(revision 13533)
+++ src/hostlist/test_gnunet_daemon_hostlist_learning.c	(working copy)
@@ -71,7 +71,7 @@
   struct GNUNET_CORE_Handle *core;
   struct GNUNET_STATISTICS_Handle *stats;
 #if START_ARM
-  pid_t arm_pid;
+  GNUNET_OS_Process *arm_proc;
 #endif
 };
 
@@ -144,24 +144,28 @@
 #if START_ARM
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Killing hostlist server ARM process.\n");
-  if (0 != PLIBC_KILL (adv_peer.arm_pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (adv_peer.arm_proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  if (GNUNET_OS_process_wait(adv_peer.arm_pid) != GNUNET_OK)
+  if (GNUNET_OS_process_wait(adv_peer.arm_proc) != GNUNET_OK)
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Hostlist server ARM process %u stopped\n", adv_peer.arm_pid);
+              "Hostlist server ARM process %u stopped\n", GNUNET_OS_process_get_pid (adv_peer.arm_proc));
+  GNUNET_OS_process_close (adv_peer->arm_proc);
+  adv_peer->arm_proc = NULL;
 #endif
   
 
 #if START_ARM
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Killing hostlist client ARM process.\n");
-  if (0 != PLIBC_KILL (learn_peer.arm_pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (learn_peer.arm_proc, SIGTERM))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
-  if (GNUNET_OS_process_wait(learn_peer.arm_pid) != GNUNET_OK)
+  if (GNUNET_OS_process_wait(learn_peer.arm_proc) != GNUNET_OK)
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Hostlist client ARM process %u stopped\n", learn_peer.arm_pid);
+              "Hostlist client ARM process %u stopped\n", GNUNET_OS_process_get_pid (learn_peer.arm_proc));
+  GNUNET_OS_process_close (learn_peer->arm_proc);
+  learn_peer->arm_proc = NULL;
 #endif
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down scheduler\n");
@@ -354,7 +358,7 @@
   unsigned int result;
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                         "gnunet-service-arm",
 #if VERBOSE
                                         "-L", "DEBUG",
@@ -397,7 +401,7 @@
 
   p->cfg = GNUNET_CONFIGURATION_create ();
 #if START_ARM
-  p->arm_pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
                                         "gnunet-service-arm",
 #if VERBOSE
                                         "-L", "DEBUG",
Index: src/testing/test_testing_topology.c
===================================================================
--- src/testing/test_testing_topology.c	(revision 13533)
+++ src/testing/test_testing_topology.c	(working copy)
@@ -179,12 +179,14 @@
 {
   char *peer_number;
   char *connect_number;
-  pid_t mem_process;
+  GNUNET_OS_Process *mem_process;
   GNUNET_asprintf(&peer_number, "%llu", num_peers);
   GNUNET_asprintf(&connect_number, "%llu", expected_connections);
   mem_process = GNUNET_OS_start_process (NULL, NULL, "./memsize.pl",
                            "memsize.pl", "totals.txt", peer_number, connect_number, NULL);
-  GNUNET_OS_process_wait(mem_process);
+  GNUNET_OS_process_wait (mem_process);
+  GNUNET_OS_process_close (mem_process);
+  mem_process = NULL;
 }
 
 #endif
Index: src/testing/testing.c
===================================================================
--- src/testing/testing.c	(revision 13533)
+++ src/testing/testing.c	(working copy)
@@ -205,7 +205,7 @@
     {
     case SP_COPYING:
       /* confirm copying complete */
-      if (GNUNET_OK != GNUNET_OS_process_status (d->pid, &type, &code))
+      if (GNUNET_OK != GNUNET_OS_process_status (d->proc, &type, &code))
         {
           if (GNUNET_TIME_absolute_get_remaining(d->max_timeout).rel_value == 0)
             {
@@ -264,7 +264,7 @@
                       "gnunet-peerinfo", "gnunet-peerinfo", "-c", d->cfgfile,
                       "-sq");
 #endif
-          d->pid = GNUNET_OS_start_process (NULL, d->pipe_stdout, "gnunet-peerinfo",
+          d->proc = GNUNET_OS_start_process (NULL, d->pipe_stdout, "gnunet-peerinfo",
                                             "gnunet-peerinfo",
                                             "-c", d->cfgfile,
                                             "-sq", NULL);
@@ -285,7 +285,7 @@
 #endif
           if (d->ssh_port_str == NULL)
             {
-              d->pid = GNUNET_OS_start_process (NULL, d->pipe_stdout, "ssh",
+              d->proc = GNUNET_OS_start_process (NULL, d->pipe_stdout, "ssh",
                                                 "ssh",
 #if !DEBUG_TESTING
                                                 "-q",
@@ -296,7 +296,7 @@
             }
           else
             {
-              d->pid = GNUNET_OS_start_process (NULL, d->pipe_stdout, "ssh",
+              d->proc = GNUNET_OS_start_process (NULL, d->pipe_stdout, "ssh",
                                                 "ssh", "-p", d->ssh_port_str,
 #if !DEBUG_TESTING
                                                 "-q",
@@ -308,7 +308,7 @@
           GNUNET_DISK_pipe_close_end(d->pipe_stdout, GNUNET_DISK_PIPE_END_WRITE);
           GNUNET_free (dst);
         }
-      if (-1 == d->pid)
+      if (NULL == d->proc)
         {
           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                       _("Could not start `%s' process to create hostkey.\n"),
@@ -378,9 +378,10 @@
           d->cb = NULL;
           GNUNET_DISK_pipe_close(d->pipe_stdout);
 	  d->pipe_stdout = NULL;
-	  (void) PLIBC_KILL (d->pid, SIGKILL);
-	  GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (d->pid));
-	  d->pid = 0;
+	  (void) GNUNET_OS_process_kill (d->proc, SIGKILL);
+	  GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (d->proc));
+	  GNUNET_OS_process_close (d->proc);
+	  d->proc = NULL;
           if (NULL != cb)
             cb (d->cb_cls,
                 NULL,
@@ -391,9 +392,10 @@
 	} 
       GNUNET_DISK_pipe_close(d->pipe_stdout);
       d->pipe_stdout = NULL;
-      (void) PLIBC_KILL (d->pid, SIGKILL);
-      GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (d->pid));
-      d->pid = 0;
+      (void) GNUNET_OS_process_kill (d->proc, SIGKILL);
+      GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (d->proc));
+      GNUNET_OS_process_close (d->proc);
+      d->proc = NULL;
 #if DEBUG_TESTING
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                   "Successfully got hostkey!\n");
@@ -439,7 +441,7 @@
                       "-L", "DEBUG",
                       "-s");
 #endif
-          d->pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-arm",
+          d->proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-arm",
                                             "gnunet-arm",
                                             "-c", d->cfgfile,
 #if DEBUG_TESTING
@@ -462,7 +464,7 @@
 #endif
           if (d->ssh_port_str == NULL)
             {
-              d->pid = GNUNET_OS_start_process (NULL, NULL, "ssh",
+              d->proc = GNUNET_OS_start_process (NULL, NULL, "ssh",
                                                 "ssh",
 #if !DEBUG_TESTING
                                                 "-q",
@@ -477,7 +479,7 @@
           else
             {
 
-              d->pid = GNUNET_OS_start_process (NULL, NULL, "ssh",
+              d->proc = GNUNET_OS_start_process (NULL, NULL, "ssh",
                                                 "ssh", "-p", d->ssh_port_str,
 #if !DEBUG_TESTING
                                                 "-q",
@@ -491,7 +493,7 @@
             }
           GNUNET_free (dst);
         }
-      if (-1 == d->pid)
+      if (NULL == d->proc)
         {
           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                       _("Could not start `%s' process to start GNUnet.\n"),
@@ -520,7 +522,7 @@
                                         &start_fsm, d);
       break;
     case SP_START_ARMING:
-      if (GNUNET_OK != GNUNET_OS_process_status (d->pid, &type, &code))
+      if (GNUNET_OK != GNUNET_OS_process_status (d->proc, &type, &code))
         {
           if (GNUNET_TIME_absolute_get_remaining(d->max_timeout).rel_value == 0)
             {
@@ -565,7 +567,7 @@
       break;
     case SP_SHUTDOWN_START:
       /* confirm copying complete */
-      if (GNUNET_OK != GNUNET_OS_process_status (d->pid, &type, &code))
+      if (GNUNET_OK != GNUNET_OS_process_status (d->proc, &type, &code))
         {
           if (GNUNET_TIME_absolute_get_remaining(d->max_timeout).rel_value == 0)
             {
@@ -645,7 +647,7 @@
       break;
     case SP_CONFIG_UPDATE:
       /* confirm copying complete */
-      if (GNUNET_OK != GNUNET_OS_process_status (d->pid, &type, &code))
+      if (GNUNET_OK != GNUNET_OS_process_status (d->proc, &type, &code))
         {
           if (GNUNET_TIME_absolute_get_remaining(d->max_timeout).rel_value == 0) /* FIXME: config update should take timeout parameter! */
             {
@@ -856,7 +858,7 @@
 
       if (ret->ssh_port_str == NULL)
         {
-          ret->pid = GNUNET_OS_start_process (NULL, NULL, "scp",
+          ret->proc = GNUNET_OS_start_process (NULL, NULL, "scp",
                                               "scp",
 #if !DEBUG_TESTING
                                               "-q",
@@ -865,7 +867,7 @@
         }
       else
         {
-          ret->pid = GNUNET_OS_start_process (NULL, NULL, "scp",
+          ret->proc = GNUNET_OS_start_process (NULL, NULL, "scp",
                                               "scp", "-P", ret->ssh_port_str,
 #if !DEBUG_TESTING
                                               "-q",
@@ -873,7 +875,7 @@
                                               ret->cfgfile, arg, NULL);
         }
       GNUNET_free (arg);
-      if (-1 == ret->pid)
+      if (NULL == ret->proc)
         {
           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                       _
@@ -972,7 +974,7 @@
       else
         arg = GNUNET_strdup (d->hostname);
 
-      d->pid = GNUNET_OS_start_process (NULL, NULL, "ssh", "ssh",
+      d->proc = GNUNET_OS_start_process (NULL, NULL, "ssh", "ssh",
 #if !DEBUG_TESTING
                                         "-q",
 #endif
@@ -991,7 +993,7 @@
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                   "Stopping gnunet-arm with config `%s' locally.\n", d->cfgfile);
 #endif
-      d->pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-arm",
+      d->proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-arm",
                                         "gnunet-arm",
 #if DEBUG_TESTING
                                         "-L", "DEBUG",
@@ -1107,7 +1109,7 @@
       else
         arg = GNUNET_strdup (d->hostname);
 
-      d->pid = GNUNET_OS_start_process (NULL, NULL, "ssh", "ssh",
+      d->proc = GNUNET_OS_start_process (NULL, NULL, "ssh", "ssh",
 #if !DEBUG_TESTING
                                         "-q",
 #endif
@@ -1127,7 +1129,7 @@
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                   "Stopping gnunet-arm with config `%s' locally.\n", d->cfgfile);
 #endif
-      d->pid = GNUNET_OS_start_process (NULL, NULL, "gnunet-arm",
+      d->proc = GNUNET_OS_start_process (NULL, NULL, "gnunet-arm",
                                         "gnunet-arm",
 #if DEBUG_TESTING
                                         "-L", "DEBUG",
@@ -1194,13 +1196,13 @@
     GNUNET_asprintf (&arg, "%s@%s:%s", d->username, d->hostname, d->cfgfile);
   else
     GNUNET_asprintf (&arg, "%s:%s", d->hostname, d->cfgfile);
-  d->pid = GNUNET_OS_start_process (NULL, NULL, "scp", "scp",
+  d->proc = GNUNET_OS_start_process (NULL, NULL, "scp", "scp",
 #if !DEBUG_TESTING
                                     "-q",
 #endif
                                     d->cfgfile, arg, NULL);
   GNUNET_free (arg);
-  if (-1 == d->pid)
+  if (NULL == d->proc)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                   _
Index: src/testing/testing_group.c
===================================================================
--- src/testing/testing_group.c	(revision 13533)
+++ src/testing/testing_group.c	(working copy)
@@ -1937,7 +1937,7 @@
   FILE *temp_friend_handle;
   unsigned int pg_iter;
   char *temp_service_path;
-  pid_t *pidarr;
+  GNUNET_OS_Process **procarr;
   char *arg;
   char * mytemp;
   enum GNUNET_OS_ProcessStatusType type;
@@ -1946,7 +1946,7 @@
   int ret;
   int max_wait = 10;
 
-  pidarr = GNUNET_malloc(sizeof(pid_t) * pg->total);
+  procarr = GNUNET_malloc(sizeof(GNUNET_OS_Process *) * pg->total);
   for (pg_iter = 0; pg_iter < pg->total; pg_iter++)
     {
       mytemp = GNUNET_DISK_mktemp("friends");
@@ -1972,7 +1972,7 @@
       if (pg->peers[pg_iter].daemon->hostname == NULL) /* Local, just copy the file */
         {
           GNUNET_asprintf (&arg, "%s/friends", temp_service_path);
-          pidarr[pg_iter] = GNUNET_OS_start_process (NULL, NULL, "mv",
+          procarr[pg_iter] = GNUNET_OS_start_process (NULL, NULL, "mv",
                                          "mv", mytemp, arg, NULL);
 #if VERBOSE_TESTING
           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1987,7 +1987,7 @@
             GNUNET_asprintf (&arg, "%s@%s:%s/friends", pg->peers[pg_iter].daemon->username, pg->peers[pg_iter].daemon->hostname, temp_service_path);
           else
             GNUNET_asprintf (&arg, "%s:%s/friends", pg->peers[pg_iter].daemon->hostname, temp_service_path);
-          pidarr[pg_iter] = GNUNET_OS_start_process (NULL, NULL, "scp",
+          procarr[pg_iter] = GNUNET_OS_start_process (NULL, NULL, "scp",
                                          "scp", mytemp, arg, NULL);
 
 #if VERBOSE_TESTING
@@ -2011,9 +2011,9 @@
           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                       _("Checking copy status of file %d\n"), pg_iter);
 #endif
-          if (pidarr[pg_iter] != 0) /* Check for already completed! */
+          if (procarr[pg_iter] != NULL) /* Check for already completed! */
             {
-              if (GNUNET_OS_process_status(pidarr[pg_iter], &type, &return_code) != GNUNET_OK)
+              if (GNUNET_OS_process_status(procarr[pg_iter], &type, &return_code) != GNUNET_OK)
                 {
                   ret = GNUNET_SYSERR;
                 }
@@ -2023,7 +2023,8 @@
                 }
               else
                 {
-                  pidarr[pg_iter] = 0;
+                  GNUNET_OS_process_close (procarr[pg_iter]);
+                  procarr[pg_iter] = NULL;
 #if VERBOSE_TESTING
             GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                       _("File %d copied\n"), pg_iter);
@@ -2043,7 +2044,7 @@
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 _("Finished copying all friend files!\n"));
 #endif
-  GNUNET_free(pidarr);
+  GNUNET_free(procarr);
   return ret;
 }
 
@@ -2063,7 +2064,7 @@
   static struct BlacklistContext blacklist_ctx;
   unsigned int pg_iter;
   char *temp_service_path;
-  pid_t *pidarr;
+  GNUNET_OS_Process **procarr;
   char *arg;
   char *mytemp;
   enum GNUNET_OS_ProcessStatusType type;
@@ -2076,7 +2077,7 @@
   char *pos;
   char *temp_transports;
 
-  pidarr = GNUNET_malloc(sizeof(pid_t) * pg->total);
+  procarr = GNUNET_malloc(sizeof(GNUNET_OS_Process *) * pg->total);
   for (pg_iter = 0; pg_iter < pg->total; pg_iter++)
     {
       mytemp = GNUNET_DISK_mktemp("blacklist");
@@ -2124,7 +2125,7 @@
       if (pg->peers[pg_iter].daemon->hostname == NULL) /* Local, just copy the file */
         {
           GNUNET_asprintf (&arg, "%s/blacklist", temp_service_path);
-          pidarr[pg_iter] = GNUNET_OS_start_process (NULL, NULL, "mv",
+          procarr[pg_iter] = GNUNET_OS_start_process (NULL, NULL, "mv",
                                          "mv", mytemp, arg, NULL);
 #if VERBOSE_TESTING
           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2139,7 +2140,7 @@
             GNUNET_asprintf (&arg, "%s@%s:%s/blacklist", pg->peers[pg_iter].daemon->username, pg->peers[pg_iter].daemon->hostname, temp_service_path);
           else
             GNUNET_asprintf (&arg, "%s:%s/blacklist", pg->peers[pg_iter].daemon->hostname, temp_service_path);
-          pidarr[pg_iter] = GNUNET_OS_start_process (NULL, NULL, "scp",
+          procarr[pg_iter] = GNUNET_OS_start_process (NULL, NULL, "scp",
                                          "scp", mytemp, arg, NULL);
 
 #if VERBOSE_TESTING
@@ -2163,9 +2164,9 @@
           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                       _("Checking copy status of file %d\n"), pg_iter);
 #endif
-          if (pidarr[pg_iter] != 0) /* Check for already completed! */
+          if (procarr[pg_iter] != NULL) /* Check for already completed! */
             {
-              if (GNUNET_OS_process_status(pidarr[pg_iter], &type, &return_code) != GNUNET_OK)
+              if (GNUNET_OS_process_status(procarr[pg_iter], &type, &return_code) != GNUNET_OK)
                 {
                   ret = GNUNET_SYSERR;
                 }
@@ -2175,7 +2176,8 @@
                 }
               else
                 {
-                  pidarr[pg_iter] = 0;
+                  GNUNET_OS_process_close (procarr[pg_iter]);
+                  procarr[pg_iter] = NULL;
 #if VERBOSE_TESTING
             GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                       _("File %d copied\n"), pg_iter);
@@ -2195,7 +2197,7 @@
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 _("Finished copying all blacklist files!\n"));
 #endif
-  GNUNET_free(pidarr);
+  GNUNET_free(procarr);
   return ret;
 }
 
Index: src/util/scheduler.c
===================================================================
--- src/util/scheduler.c	(revision 13533)
+++ src/util/scheduler.c	(working copy)
@@ -633,7 +633,7 @@
       if (sched->current_priority != pos->priority)
 	{
 	  sched->current_priority = pos->priority;
-	  (void) GNUNET_OS_set_process_priority (0, pos->priority);
+	  (void) GNUNET_OS_set_process_priority (GNUNET_OS_process_current (), pos->priority);
 	}
       sched->active_task = pos;
 #if PROFILE_DELAYS
Index: src/util/os_priority.c
===================================================================
--- src/util/os_priority.c	(revision 13533)
+++ src/util/os_priority.c	(working copy)
@@ -29,24 +29,130 @@
 #include "gnunet_os_lib.h"
 #include "disk.h"
 
+struct _GNUNET_OS_Process
+{
+  pid_t pid;
 #if WINDOWS
+  HANDLE handle;
+#endif
+};
+
+static GNUNET_OS_Process current_process;
+
+GNUNET_OS_Process *
+GNUNET_OS_process_alloc ()
+{
+  GNUNET_OS_Process *ret = GNUNET_malloc (sizeof (GNUNET_OS_Process));
+  ret->pid = 0;
+#if WINDOWS
+  ret->handle = NULL;
+#endif
+  return ret;
+}
+
+/**
+ * Get process structure for current process
+ *
+ * The pointer it returns points to static memory location and must not be
+ * deallocated/closed
+ *
+ * @return pointer to the process sturcutre for this process
+ */
+GNUNET_OS_Process *
+GNUNET_OS_process_current ()
+{
+#if WINDOWS
+  current_process.pid = GetCurrentProcessId ();
+  current_process.handle = GetCurrentProcess ();
+#else
+  current_process.pid = 0;
+#endif
+  return &current_process;
+}
+
+int
+GNUNET_OS_process_kill (GNUNET_OS_Process *proc, int sig)
+{
+#if WINDOWS
+  if (sig == SIGKILL || sig == SIGTERM)
+  {
+    HANDLE h = GNUNET_OS_process_get_handle (proc);
+    if (NULL == h)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Invalid process information {%d, %08X}\n", GNUNET_OS_process_get_pid (proc), h);
+      return -1;
+    }
+    if (!TerminateProcess (h, 0))
+    {
+      SetErrnoFromWinError (GetLastError ());
+      return -1;
+    }
+    else
+      return 0;
+  }
+  errno = EINVAL;
+  return -1;
+#else
+  return kill (GNUNET_OS_process_get_pid (proc), sig);
+#endif
+}
+
+pid_t
+GNUNET_OS_process_get_pid (GNUNET_OS_Process *proc)
+{
+  return proc->pid;
+}
+
+void
+GNUNET_OS_process_set_pid (GNUNET_OS_Process *proc, pid_t pid)
+{
+  proc->pid = pid;
+}
+
+#if WINDOWS
+HANDLE
+GNUNET_OS_process_get_handle (GNUNET_OS_Process *proc)
+{
+  return proc->handle;
+}
+
+void
+GNUNET_OS_process_set_handle(GNUNET_OS_Process *proc, HANDLE handle)
+{
+  if (proc->handle != NULL)
+    CloseHandle (proc->handle);
+  proc->handle = handle;
+}
+#endif
+
+void
+GNUNET_OS_process_close (GNUNET_OS_Process *proc)
+{
+#if WINDOWS
+  if (proc->handle != NULL)
+    CloseHandle (proc->handle);
+#endif  
+  GNUNET_free (proc);
+}
+
+#if WINDOWS
 #include "gnunet_signal_lib.h"
 
 extern GNUNET_SIGNAL_Handler w32_sigchld_handler;
 
 /**
  * @brief Waits for a process to terminate and invokes the SIGCHLD handler
- * @param h handle to the process
+ * @param proc pointer to process structure
  */
 static DWORD WINAPI
-ChildWaitThread (HANDLE h)
+ChildWaitThread (void *arg)
 {
-  WaitForSingleObject (h, INFINITE);
+  GNUNET_OS_Process *proc = (GNUNET_OS_Process *) arg;
+  WaitForSingleObject (proc->handle, INFINITE);
 
   if (w32_sigchld_handler)
     w32_sigchld_handler ();
 
-  CloseHandle (h);
   return 0;
 }
 #endif
@@ -54,19 +160,21 @@
 /**
  * Set process priority
  *
- * @param proc id of the process
+ * @param proc pointer to process structure
  * @param prio priority value
  * @return GNUNET_OK on success, GNUNET_SYSERR on error
  */
 int
-GNUNET_OS_set_process_priority (pid_t proc,
+GNUNET_OS_set_process_priority (GNUNET_OS_Process *proc,
                                 enum GNUNET_SCHEDULER_Priority prio)
 {
   int rprio;
+  pid_t pid;
 
   GNUNET_assert (prio < GNUNET_SCHEDULER_PRIORITY_COUNT);
   if (prio == GNUNET_SCHEDULER_PRIORITY_KEEP)
     return GNUNET_OK;
+
   /* convert to MINGW/Unix values */
   switch (prio)
     {
@@ -114,12 +222,19 @@
       GNUNET_assert (0);
       return GNUNET_SYSERR;
     }
+
+  pid = GNUNET_OS_process_get_pid (proc);
+
   /* Set process priority */
 #ifdef MINGW
-  SetPriorityClass (GetCurrentProcess (), rprio);
+  {
+    HANDLE h = GNUNET_OS_process_get_handle (proc);
+    GNUNET_assert (h != NULL);
+    SetPriorityClass (h, rprio);
+  }
 #elif LINUX 
-  if ( (0 == proc) ||
-       (proc == getpid () ) )
+  if ( (0 == pid) ||
+       (pid == getpid () ) )
     {
       int have = nice (0);
       int delta = rprio - have;
@@ -135,7 +250,7 @@
     }
   else
     {
-      if (0 != setpriority (PRIO_PROCESS, proc, rprio))
+      if (0 != setpriority (PRIO_PROCESS, pid, rprio))
 
         {
           GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING |
@@ -157,18 +272,18 @@
  * @param pipe_stdout pipe to use to get output from child process (or NULL)
  * @param filename name of the binary
  * @param ... NULL-terminated list of arguments to the process
- * @return process ID of the new process, -1 on error
+ * @return pointer to process structure of the new process, NULL on error
  */
-pid_t
+GNUNET_OS_Process *
 GNUNET_OS_start_process (struct GNUNET_DISK_PipeHandle *pipe_stdin, 
 			 struct GNUNET_DISK_PipeHandle *pipe_stdout,
 			 const char *filename, ...)
 {
-  /* FIXME:  Make this work on windows!!! */
   va_list ap;
 
 #ifndef MINGW
   pid_t ret;
+  GNUNET_OS_Process *gnunet_proc = NULL;
   char **argv;
   int argc;
   int fd_stdout_write;
@@ -227,9 +342,11 @@
             GNUNET_DISK_pipe_close_end(pipe_stdin, GNUNET_DISK_PIPE_END_READ);
           sleep (1);
 #endif
+          gnunet_proc = GNUNET_OS_process_alloc ();
+          GNUNET_OS_process_set_pid (gnunet_proc, ret);
         }
       GNUNET_free (argv);
-      return ret;
+      return gnunet_proc;
     }
 
   if (pipe_stdout != NULL)
@@ -258,6 +375,7 @@
   int findresult;
   STARTUPINFO start;
   PROCESS_INFORMATION proc;
+  GNUNET_OS_Process *gnunet_proc = NULL;
 
   HANDLE stdin_handle;
   HANDLE stdout_handle;
@@ -299,7 +417,7 @@
     {
       SetErrnoFromWinError (GetLastError ());
       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "FindExecutable", filename);
-      return (pid_t) -1;
+      return NULL;
     }
 
   if (!CreateProcessA
@@ -308,16 +426,20 @@
     {
       SetErrnoFromWinError (GetLastError ());
       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "CreateProcess", path);
-      return (pid_t) -1;
+      return NULL;
     }
 
-  CreateThread (NULL, 64000, ChildWaitThread, proc.hProcess, 0, NULL);
+  gnunet_proc = GNUNET_OS_process_alloc ();
+  GNUNET_OS_process_set_pid (gnunet_proc, proc.dwProcessId);
+  GNUNET_OS_process_set_handle (gnunet_proc, proc.hProcess);
 
+  CreateThread (NULL, 64000, ChildWaitThread, (void *) gnunet_proc, 0, NULL);
+
   CloseHandle (proc.hThread);
 
   GNUNET_free (cmd);
 
-  return proc.dwProcessId;
+  return gnunet_proc;
 #endif
 
 }
@@ -333,7 +455,7 @@
  * @param argv NULL-terminated list of arguments to the process
  * @return process ID of the new process, -1 on error
  */
-pid_t
+GNUNET_OS_Process *
 GNUNET_OS_start_process_v (const int *lsocks,
 			   const char *filename, char *const argv[])
 {
@@ -341,6 +463,7 @@
   pid_t ret;
   char lpid[16];
   char fds[16];
+  GNUNET_OS_Process *gnunet_proc = NULL;
   int i;
   int j;
   int k;
@@ -382,9 +505,11 @@
              be plenty in practice */
           sleep (1);
 #endif
+          gnunet_proc = GNUNET_OS_process_alloc ();
+          GNUNET_OS_process_set_pid (gnunet_proc, ret);
         }
       GNUNET_array_grow (lscp, ls, 0);
-      return ret;
+      return gnunet_proc;
     }
   if (lscp != NULL)
     {
@@ -441,6 +566,7 @@
   int argcount = 0;
   char *non_const_filename = NULL;
   int filenamelen = 0;
+  GNUNET_OS_Process *gnunet_proc = NULL;
 
   GNUNET_assert (lsocks == NULL);
   /* Count the number of arguments */
@@ -504,12 +630,16 @@
        &proc))
     {
       SetErrnoFromWinError (GetLastError ());
-      GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fork");
-      return -1;
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "CreateProcess");
+      return NULL;
     }
 
-  CreateThread (NULL, 64000, ChildWaitThread, proc.hProcess, 0, NULL);
+  gnunet_proc = GNUNET_OS_process_alloc ();
+  GNUNET_OS_process_set_pid (gnunet_proc, proc.dwProcessId);
+  GNUNET_OS_process_set_handle (gnunet_proc, proc.hProcess);
 
+  CreateThread (NULL, 64000, ChildWaitThread, (void *) gnunet_proc, 0, NULL);
+
   CloseHandle (proc.hThread);
   GNUNET_free (cmd);
 
@@ -517,7 +647,7 @@
     GNUNET_free (non_const_argv[--argcount]);
   GNUNET_free (non_const_argv);
 
-  return proc.dwProcessId;
+  return gnunet_proc;
 #endif
 }
 
@@ -529,7 +659,7 @@
  * @return GNUNET_OK on success, GNUNET_NO if the process is still running, GNUNET_SYSERR otherwise
  */
 int
-GNUNET_OS_process_status (pid_t proc, enum GNUNET_OS_ProcessStatusType *type,
+GNUNET_OS_process_status (GNUNET_OS_Process *proc, enum GNUNET_OS_ProcessStatusType *type,
                           unsigned long *code)
 {
 #ifndef MINGW
@@ -537,7 +667,7 @@
   int ret;
 
   GNUNET_assert (0 != proc);
-  ret = waitpid (proc, &status, WNOHANG);
+  ret = waitpid (GNUNET_OS_process_get_pid (proc), &status, WNOHANG);
   if (ret < 0)
     {
       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
@@ -549,7 +679,7 @@
       *code = 0;
       return GNUNET_NO;
     }
-  if (proc != ret)
+  if (GNUNET_OS_process_get_pid (proc) != ret)
     {
       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
       return GNUNET_SYSERR;
@@ -583,27 +713,35 @@
     }
 #else
   HANDLE h;
-  DWORD c;
+  DWORD c, error_code, ret;
 
-  h = OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, proc);
-  if (INVALID_HANDLE_VALUE == h)
+  h = GNUNET_OS_process_get_handle (proc);
+  ret = GNUNET_OS_process_get_pid (proc);
+  if (h == NULL || ret == 0)
     {
-      SetErrnoFromWinError (GetLastError ());
-      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "OpenProcess");
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Invalid process information {%d, %08X}\n", ret, h);
       return GNUNET_SYSERR;
     }
+  if (h == NULL)
+    h = GetCurrentProcess ();
 
-  c = GetExitCodeProcess (h, &c);
+  SetLastError (0);
+  ret = GetExitCodeProcess (h, &c);
+  error_code = GetLastError ();
+  if (ret == 0 || error_code != NO_ERROR)
+  {
+      SetErrnoFromWinError (error_code);
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "GetExitCodeProcess");
+      return GNUNET_SYSERR;
+  }
   if (STILL_ACTIVE == c)
     {
       *type = GNUNET_OS_PROCESS_RUNNING;
       *code = 0;
-      CloseHandle (h);
       return GNUNET_NO;
     }
   *type = GNUNET_OS_PROCESS_EXITED;
   *code = c;
-  CloseHandle (h);
 #endif
 
   return GNUNET_OK;
@@ -611,14 +749,15 @@
 
 /**
  * Wait for a process
- * @param proc process ID to wait for
+ * @param proc pointer to process structure
  * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
  */
 int
-GNUNET_OS_process_wait (pid_t proc)
+GNUNET_OS_process_wait (GNUNET_OS_Process *proc)
 {
+  pid_t pid = GNUNET_OS_process_get_pid (proc);
 #ifndef MINGW
-  if (proc != waitpid (proc, NULL, 0))
+  if (pid != waitpid (pid, NULL, 0))
     return GNUNET_SYSERR;
 
   return GNUNET_OK;
@@ -626,12 +765,14 @@
   HANDLE h;
   int ret;
 
-  h = OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, proc);
-  if (INVALID_HANDLE_VALUE == h)
+  h = GNUNET_OS_process_get_handle (proc);
+  if (NULL == h)
     {
-      SetErrnoFromWinError (GetLastError ());
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Invalid process information {%d, %08X}\n", pid, h);
       return GNUNET_SYSERR;
     }
+  if (h == NULL)
+    h = GetCurrentProcess ();
 
   if (WAIT_OBJECT_0 != WaitForSingleObject (h, INFINITE))
     {
@@ -641,8 +782,6 @@
   else
     ret = GNUNET_OK;
 
-  CloseHandle (h);
-
   return ret;
 #endif
 }
Index: src/util/test_os_priority.c
===================================================================
--- src/util/test_os_priority.c	(revision 13533)
+++ src/util/test_os_priority.c	(working copy)
@@ -32,27 +32,27 @@
 {
   pid_t child;
   if (GNUNET_OK !=
-      GNUNET_OS_set_process_priority (getpid (),
+      GNUNET_OS_set_process_priority (GNUNET_OS_process_current (),
                                       GNUNET_SCHEDULER_PRIORITY_DEFAULT))
     return 1;
   if (GNUNET_OK !=
-      GNUNET_OS_set_process_priority (getpid (),
+      GNUNET_OS_set_process_priority (GNUNET_OS_process_current (),
                                       GNUNET_SCHEDULER_PRIORITY_UI))
     return 1;
   if (GNUNET_OK !=
-      GNUNET_OS_set_process_priority (getpid (),
+      GNUNET_OS_set_process_priority (GNUNET_OS_process_current (),
                                       GNUNET_SCHEDULER_PRIORITY_IDLE))
     return 1;
   if (GNUNET_OK !=
-      GNUNET_OS_set_process_priority (getpid (),
+      GNUNET_OS_set_process_priority (GNUNET_OS_process_current (),
                                       GNUNET_SCHEDULER_PRIORITY_BACKGROUND))
     return 1;
   if (GNUNET_OK !=
-      GNUNET_OS_set_process_priority (getpid (),
+      GNUNET_OS_set_process_priority (GNUNET_OS_process_current (),
                                       GNUNET_SCHEDULER_PRIORITY_HIGH))
     return 1;
   if (GNUNET_OK !=
-      GNUNET_OS_set_process_priority (getpid (),
+      GNUNET_OS_set_process_priority (GNUNET_OS_process_current (),
                                       GNUNET_SCHEDULER_PRIORITY_HIGH))
     return 1;
 #ifndef MINGW
Index: src/util/test_os_start_process.c
===================================================================
--- src/util/test_os_start_process.c	(revision 13533)
+++ src/util/test_os_start_process.c	(working copy)
@@ -38,7 +38,7 @@
 static char *test_phrase = "HELLO WORLD";
 static int ok;
 
-static pid_t pid;
+static GNUNET_OS_Process *proc;
 /* Pipe to write to started processes stdin (on write end) */
 static struct GNUNET_DISK_PipeHandle *hello_pipe_stdin;
 /* Pipe to read from started processes stdout (on read end) */
@@ -50,11 +50,13 @@
 end_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
 
-  if (0 != PLIBC_KILL (pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (proc, SIGTERM))
     {
       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
     }
-  GNUNET_OS_process_wait (pid);
+  GNUNET_OS_process_wait (proc);
+  GNUNET_OS_process_close (proc);
+  proc = NULL;
   GNUNET_DISK_pipe_close(hello_pipe_stdout);
   GNUNET_DISK_pipe_close(hello_pipe_stdin);
 }
@@ -119,7 +121,7 @@
       return;
     }
 
-  pid = GNUNET_OS_start_process (hello_pipe_stdin, hello_pipe_stdout, fn,
+  proc = GNUNET_OS_start_process (hello_pipe_stdin, hello_pipe_stdout, fn,
                                  "test_gnunet_echo_hello", "-", NULL);
   GNUNET_free (fn);
 
Index: src/util/crypto_random.c
===================================================================
--- src/util/crypto_random.c	(revision 13533)
+++ src/util/crypto_random.c	(working copy)
@@ -188,7 +188,7 @@
  * Process ID of the "find" process that we use for
  * entropy gathering.
  */
-static pid_t genproc;
+static GNUNET_OS_Process *genproc;
 
 /**
  * Function called by libgcrypt whenever we are
@@ -206,16 +206,17 @@
     return;
   if (current == total)
     {
-      if (genproc != 0)
+      if (genproc != NULL)
         {
-          if (0 != PLIBC_KILL (genproc, SIGTERM))
+          if (0 != GNUNET_OS_process_kill (genproc, SIGTERM))
             GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "kill");
           GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (genproc));
-          genproc = 0;
+          GNUNET_OS_process_close (genproc);
+          genproc = NULL;
         }
       return;
     }
-  if (genproc != 0)
+  if (genproc != NULL)
     {
       ret = GNUNET_OS_process_status (genproc, &type, &code);
       if (ret == GNUNET_NO)
@@ -225,10 +226,11 @@
           GNUNET_break (0);
           return;
         }
-      if (0 != PLIBC_KILL (genproc, SIGTERM))
+      if (0 != GNUNET_OS_process_kill (genproc, SIGTERM))
         GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "kill");
       GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (genproc));
-      genproc = 0;
+      GNUNET_OS_process_close (genproc);
+      genproc = NULL;
     }
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               _("Starting `%s' process to generate entropy\n"), "find");
@@ -243,10 +245,11 @@
 static void
 killfind ()
 {
-  if (genproc != 0)
+  if (genproc != NULL)
     {
-      PLIBC_KILL (genproc, SIGKILL);
-      genproc = 0;
+      GNUNET_OS_process_kill (genproc, SIGKILL);
+      GNUNET_OS_process_close (genproc);
+      genproc = NULL;
     }
 }
 
@@ -279,3 +282,4 @@
 
 
 /* end of crypto_random.c */
+
Index: src/util/test_resolver_api.c
===================================================================
--- src/util/test_resolver_api.c	(revision 13533)
+++ src/util/test_resolver_api.c	(working copy)
@@ -360,7 +360,7 @@
   int ok = 1 + 2 + 4 + 8;
   char *fn;
   char *pfx;
-  pid_t pid;
+  GNUNET_OS_Process *proc;
   char * const argv[] =
     { "test-resolver-api", "-c", "test_resolver_api_data.conf",
 #if VERBOSE
@@ -372,7 +372,7 @@
   pfx = GNUNET_OS_installation_get_path(GNUNET_OS_IPK_BINDIR);
   GNUNET_asprintf(&fn, "%s%cgnunet-service-resolver", pfx, DIR_SEPARATOR);
   GNUNET_free(pfx);
-  pid = GNUNET_OS_start_process(NULL, NULL, fn, "gnunet-service-resolver",
+  proc = GNUNET_OS_start_process(NULL, NULL, fn, "gnunet-service-resolver",
 #if VERBOSE
       "-L", "DEBUG",
 #endif
@@ -380,12 +380,14 @@
   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 != PLIBC_KILL(pid, SIGTERM))
+  if (0 != GNUNET_OS_process_kill (proc, SIGTERM))
     {
       GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING, "kill");
       ok = 1;
     }
-  GNUNET_OS_process_wait(pid);
+  GNUNET_OS_process_wait (proc);
+  GNUNET_OS_process_close (proc);
+  proc = NULL;
   if (ok != 0)
     fprintf(stderr, "Missed some resolutions: %u\n", ok);
   return ok;
GNUNET_OS_Process.diff (101,402 bytes)   

Activities

Christian Grothoff

2010-11-03 20:59

manager   ~0004138

Given that we're talking about processes, I don't consider the extra malloc even worth mentioning as a concern. Also, under UNIX we must not have un-wait-ed pids to avoid creating zombies, so I don't think it is likely that this will create leaks.

Christian Grothoff

2010-11-03 22:39

manager   ~0004140

Patch applied (SVN 13540 and 13541).

Issue History

Date Modified Username Field Change
2010-11-03 17:10 LRN New Issue
2010-11-03 17:10 LRN Status new => assigned
2010-11-03 17:10 LRN Assigned To => NDurner
2010-11-03 17:10 LRN File Added: GNUNET_OS_Process.diff
2010-11-03 20:59 Christian Grothoff Note Added: 0004138
2010-11-03 20:59 Christian Grothoff Assigned To NDurner => LRN
2010-11-03 22:39 Christian Grothoff Note Added: 0004140
2010-11-03 22:39 Christian Grothoff Status assigned => resolved
2010-11-03 22:39 Christian Grothoff Resolution open => fixed
2010-12-23 23:50 Christian Grothoff Status resolved => closed
2024-01-12 14:28 schanzen Category Win32 port => Win32 port (deprecated)
2024-05-03 13:51 Christian Grothoff Category Win32 port (deprecated) => obsolete