aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/build/hook-instance.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/build/hook-instance.cc')
-rw-r--r--src/libstore/build/hook-instance.cc71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/libstore/build/hook-instance.cc b/src/libstore/build/hook-instance.cc
new file mode 100644
index 000000000..a33d5e22b
--- /dev/null
+++ b/src/libstore/build/hook-instance.cc
@@ -0,0 +1,71 @@
+#include "build.hh"
+
+namespace nix {
+
+HookInstance::HookInstance()
+{
+ debug("starting build hook '%s'", settings.buildHook);
+
+ /* Create a pipe to get the output of the child. */
+ fromHook.create();
+
+ /* Create the communication pipes. */
+ toHook.create();
+
+ /* Create a pipe to get the output of the builder. */
+ builderOut.create();
+
+ /* Fork the hook. */
+ pid = startProcess([&]() {
+
+ commonChildInit(fromHook);
+
+ if (chdir("/") == -1) throw SysError("changing into /");
+
+ /* Dup the communication pipes. */
+ if (dup2(toHook.readSide.get(), STDIN_FILENO) == -1)
+ throw SysError("dupping to-hook read side");
+
+ /* Use fd 4 for the builder's stdout/stderr. */
+ if (dup2(builderOut.writeSide.get(), 4) == -1)
+ throw SysError("dupping builder's stdout/stderr");
+
+ /* Hack: pass the read side of that fd to allow build-remote
+ to read SSH error messages. */
+ if (dup2(builderOut.readSide.get(), 5) == -1)
+ throw SysError("dupping builder's stdout/stderr");
+
+ Strings args = {
+ std::string(baseNameOf(settings.buildHook.get())),
+ std::to_string(verbosity),
+ };
+
+ execv(settings.buildHook.get().c_str(), stringsToCharPtrs(args).data());
+
+ throw SysError("executing '%s'", settings.buildHook);
+ });
+
+ pid.setSeparatePG(true);
+ fromHook.writeSide = -1;
+ toHook.readSide = -1;
+
+ sink = FdSink(toHook.writeSide.get());
+ std::map<std::string, Config::SettingInfo> settings;
+ globalConfig.getSettings(settings);
+ for (auto & setting : settings)
+ sink << 1 << setting.first << setting.second.value;
+ sink << 0;
+}
+
+
+HookInstance::~HookInstance()
+{
+ try {
+ toHook.writeSide = -1;
+ if (pid != -1) pid.kill();
+ } catch (...) {
+ ignoreException();
+ }
+}
+
+}