aboutsummaryrefslogtreecommitdiff
path: root/src/libutil
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2012-11-09 18:00:33 +0100
committerEelco Dolstra <eelco.dolstra@logicblox.com>2012-11-09 18:00:33 +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 7e5d8bb80..bb59b0924 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 0e121ea5c..90413b0ef 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. */