about summary refs log tree commit diff
path: root/src/libutil
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2012-11-09T17·00+0100
committerEelco Dolstra <eelco.dolstra@logicblox.com>2012-11-09T17·00+0100
commitea89df2b76811505239b508a570ac9c0ea591038 (patch)
tree7b11ea7186ad2b73bf12ebb2e51e7238a052db85 /src/libutil
parent48c19c4633b1443015531ee3032b16b29b0a92f9 (diff)
Use vfork() instead of fork() if available
Hopefully this reduces the chance of hitting ‘unable to fork: Cannot
allocate memory’ errors.  vfork() is used for everything except
starting builders.
Diffstat (limited to 'src/libutil')
-rw-r--r--src/libutil/util.cc14
-rw-r--r--src/libutil/util.hh3
2 files changed, 14 insertions, 3 deletions
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index 7e5d8bb8056a..bb59b09240ca 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -760,8 +760,8 @@ Pid::operator pid_t()
 
 void Pid::kill()
 {
-    if (pid == -1) return;
-    
+    if (pid == -1 || pid == 0) return;
+
     printMsg(lvlError, format("killing process %1%") % pid);
 
     /* Send the requested signal to the child.  If it has its own
@@ -883,7 +883,8 @@ string runProgram(Path program, bool searchPath, const Strings & args)
 
     /* Fork. */
     Pid pid;
-    pid = fork();
+    pid = maybeVfork();
+
     switch (pid) {
 
     case -1:
@@ -955,6 +956,13 @@ void setuidCleanup()
 }
 
 
+#if HAVE_VFORK
+pid_t (*maybeVfork)() = vfork;
+#else
+pid_t (*maybeVfork)() = fork;
+#endif
+
+
 //////////////////////////////////////////////////////////////////////
 
 
diff --git a/src/libutil/util.hh b/src/libutil/util.hh
index 0e121ea5c602..90413b0efe04 100644
--- a/src/libutil/util.hh
+++ b/src/libutil/util.hh
@@ -266,6 +266,9 @@ void closeOnExec(int fd);
    sanitize file handles 0, 1 and 2. */
 void setuidCleanup();
 
+/* Call vfork() if available, otherwise fork(). */
+extern pid_t (*maybeVfork)();
+
 
 /* User interruption. */