gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r9189 - in gnunet/src: include util


From: gnunet
Subject: [GNUnet-SVN] r9189 - in gnunet/src: include util
Date: Mon, 19 Oct 2009 03:35:56 -0600

Author: grothoff
Date: 2009-10-19 03:35:56 -0600 (Mon, 19 Oct 2009)
New Revision: 9189

Modified:
   gnunet/src/include/platform.h
   gnunet/src/util/os_priority.c
Log:
use vfork if available, otherwise sleep after fork to avoid racing on 
signalling the process vs execvp changing the signal handlers; clone without 
signal-handlers would also do, but is even less portable

Modified: gnunet/src/include/platform.h
===================================================================
--- gnunet/src/include/platform.h       2009-10-19 09:33:40 UTC (rev 9188)
+++ gnunet/src/include/platform.h       2009-10-19 09:35:56 UTC (rev 9189)
@@ -151,6 +151,10 @@
 #include <errno.h>
 #include <limits.h>
 
+#if HAVE_VFORK_H
+#include <vfork.h>
+#endif
+
 #if HAVE_CTYPE_H
 #include <ctype.h>
 #endif

Modified: gnunet/src/util/os_priority.c
===================================================================
--- gnunet/src/util/os_priority.c       2009-10-19 09:33:40 UTC (rev 9188)
+++ gnunet/src/util/os_priority.c       2009-10-19 09:35:56 UTC (rev 9189)
@@ -116,7 +116,6 @@
 }
 
 
-
 /**
  * Start a process.
  *
@@ -134,11 +133,31 @@
   char **argv;
   int argc;
 
+#if HAVE_WORKING_VFORK
+  ret = vfork ();
+#else
   ret = fork ();
+#endif
   if (ret != 0)
     {
       if (ret == -1)
-        GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fork");
+       {
+         GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fork");
+       }
+      else
+       {
+#if HAVE_WORKING_VFORK
+         /* let's hope vfork actually works; for some extreme cases (including
+            a testcase) we need 'execvp' to have run before we return, since
+            we may send a signal to the process next and we don't want it
+            to be caught by OUR signal handler (but either by the default
+            handler or the actual handler as installed by the process itself). 
*/
+#else
+         /* let's give the child process a chance to run execvp, 1s should
+            be plenty in practice */
+         sleep (1);
+#endif
+       }
       return ret;
     }
   argc = 0;
@@ -154,7 +173,7 @@
   va_end (ap);
   execvp (filename, argv);
   GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "execvp", filename);
-  exit (1);
+  _exit (1);
 #else
   char *arg;
   unsigned int cmdlen;
@@ -209,16 +228,36 @@
 #ifndef MINGW
   pid_t ret;
 
+#if HAVE_WORKING_VFORK
+  ret = vfork ();
+#else
   ret = fork ();
+#endif
   if (ret != 0)
     {
       if (ret == -1)
-        GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fork");
+       {
+         GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fork");
+       }
+      else
+       {
+#if HAVE_WORKING_VFORK
+         /* let's hope vfork actually works; for some extreme cases (including
+            a testcase) we need 'execvp' to have run before we return, since
+            we may send a signal to the process next and we don't want it
+            to be caught by OUR signal handler (but either by the default
+            handler or the actual handler as installed by the process itself). 
*/
+#else
+         /* let's give the child process a chance to run execvp, 1s should
+            be plenty in practice */
+         sleep (1);
+#endif
+       }
       return ret;
     }
   execvp (filename, argv);
   GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "execvp", filename);
-  exit (1);
+  _exit (1);
 #else
   char **arg;
   unsigned int cmdlen;





reply via email to

[Prev in Thread] Current Thread [Next in Thread]