aboutsummaryrefslogtreecommitdiff
path: root/src/libutil
diff options
context:
space:
mode:
Diffstat (limited to 'src/libutil')
-rw-r--r--src/libutil/util.cc29
-rw-r--r--src/libutil/util.hh2
2 files changed, 31 insertions, 0 deletions
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index 9804e9a51..53342b5cb 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -1660,4 +1660,33 @@ string showBytes(uint64_t bytes)
}
+void commonChildInit(Pipe & logPipe)
+{
+ const static string pathNullDevice = "/dev/null";
+ restoreSignals();
+
+ /* Put the child in a separate session (and thus a separate
+ process group) so that it has no controlling terminal (meaning
+ that e.g. ssh cannot open /dev/tty) and it doesn't receive
+ terminal signals. */
+ if (setsid() == -1)
+ throw SysError("creating a new session");
+
+ /* Dup the write side of the logger pipe into stderr. */
+ if (dup2(logPipe.writeSide.get(), STDERR_FILENO) == -1)
+ throw SysError("cannot pipe standard error into log file");
+
+ /* Dup stderr to stdout. */
+ if (dup2(STDERR_FILENO, STDOUT_FILENO) == -1)
+ throw SysError("cannot dup stderr into stdout");
+
+ /* Reroute stdin to /dev/null. */
+ int fdDevNull = open(pathNullDevice.c_str(), O_RDWR);
+ if (fdDevNull == -1)
+ throw SysError("cannot open '%1%'", pathNullDevice);
+ if (dup2(fdDevNull, STDIN_FILENO) == -1)
+ throw SysError("cannot dup null device into stdin");
+ close(fdDevNull);
+}
+
}
diff --git a/src/libutil/util.hh b/src/libutil/util.hh
index 129d59a97..cafe93702 100644
--- a/src/libutil/util.hh
+++ b/src/libutil/util.hh
@@ -536,6 +536,8 @@ typedef std::function<bool(const Path & path)> PathFilter;
extern PathFilter defaultPathFilter;
+/* Common initialisation performed in child processes. */
+void commonChildInit(Pipe & logPipe);
/* Create a Unix domain socket in listen mode. */
AutoCloseFD createUnixDomainSocket(const Path & path, mode_t mode);