diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 27717a816..6f3c110a3 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -1,12 +1,64 @@ +#include "serialise.hh" +#include "util.hh" #include "remote-store.hh" +#include +#include + namespace nix { RemoteStore::RemoteStore() { - throw Error("not implemented"); + toChild.create(); + fromChild.create(); + + + /* Start the worker. */ + string worker = "nix-worker"; + + child = fork(); + + switch (child) { + + case -1: + throw SysError("unable to fork"); + + case 0: + try { /* child */ + + fromChild.readSide.close(); + if (dup2(fromChild.writeSide, STDOUT_FILENO) == -1) + throw SysError("dupping write side"); + + toChild.writeSide.close(); + if (dup2(toChild.readSide, STDIN_FILENO) == -1) + throw SysError("dupping read side"); + + execlp(worker.c_str(), worker.c_str(), + "-vvv", "--slave", NULL); + + throw SysError(format("executing `%1%'") % worker); + + } catch (std::exception & e) { + std::cerr << format("child error: %1%\n") % e.what(); + } + quickExit(1); + } + + fromChild.writeSide.close(); + toChild.readSide.close(); + + from.fd = fromChild.readSide; + to.fd = toChild.writeSide; + + + /* Send the magic greeting, check for the reply. */ + writeInt(0x6e697864, to); + + unsigned int magic = readInt(from); + if (magic != 0x6478696e) throw Error("protocol mismatch"); } diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh index 8ebe5e397..da6911cf4 100644 --- a/src/libstore/remote-store.hh +++ b/src/libstore/remote-store.hh @@ -9,6 +9,12 @@ namespace nix { +class Pipe; +class Pid; +struct FdSink; +struct FdSource; + + class RemoteStore : public StoreAPI { public: @@ -44,6 +50,11 @@ public: void ensurePath(const Path & storePath); private: + Pipe toChild; + Pipe fromChild; + FdSink to; + FdSource from; + Pid child; }; diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index 092d7f1e9..9e8bc36d7 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -91,6 +91,7 @@ Path makeFixedOutputPath(bool recursive, #include "local-store.hh" +#include "serialise.hh" #include "remote-store.hh" diff --git a/src/libutil/serialise.hh b/src/libutil/serialise.hh index 459a693ee..6be10b552 100644 --- a/src/libutil/serialise.hh +++ b/src/libutil/serialise.hh @@ -33,6 +33,11 @@ struct FdSink : Sink { int fd; + FdSink() + { + fd = 0; + } + FdSink(int fd) { this->fd = fd; @@ -47,6 +52,11 @@ struct FdSource : Source { int fd; + FdSource() + { + fd = 0; + } + FdSource(int fd) { this->fd = fd; diff --git a/src/nix-worker/main.cc b/src/nix-worker/main.cc index 4fe92a85a..f71b604d0 100644 --- a/src/nix-worker/main.cc +++ b/src/nix-worker/main.cc @@ -1,35 +1,21 @@ #include "shared.hh" #include "local-store.hh" #include "util.hh" +#include "serialise.hh" using namespace nix; -/* !!! Mostly cut&pasted from util/archive.hh */ -/* Use buffered reads. */ -static unsigned int readInt(int fd) +void processConnection(Source & from, Sink & to) { - unsigned char buf[8]; - readFull(fd, buf, sizeof(buf)); - if (buf[4] || buf[5] || buf[6] || buf[7]) - throw Error("implementation cannot deal with > 32-bit integers"); - return - buf[0] | - (buf[1] << 8) | - (buf[2] << 16) | - (buf[3] << 24); -} + store = boost::shared_ptr(new LocalStore(true)); - -void processConnection(int fdFrom, int fdTo) -{ - store = openStore(); - - unsigned int magic = readInt(fdFrom); + unsigned int magic = readInt(from); if (magic != 0x6e697864) throw Error("protocol mismatch"); - - + writeInt(0x6478696e, to); + + debug("greeting exchanged"); } @@ -43,8 +29,11 @@ void run(Strings args) if (arg == "--slave") slave = true; } - if (slave) - processConnection(STDIN_FILENO, STDOUT_FILENO); + if (slave) { + FdSource source(STDIN_FILENO); + FdSink sink(STDOUT_FILENO); + processConnection(source, sink); + } else if (daemon) throw Error("daemon mode not implemented");