about summary refs log tree commit diff
path: root/src/nix-instantiate/main.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2005-02-01T12·36+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2005-02-01T12·36+0000
commitdcc37c236c66ba463bd61fec23d046485d8a412f (patch)
treeb1a34feaf2a9a0ca0e0bad89c1671289de9e19d2 /src/nix-instantiate/main.cc
parenta6b65fd5e107416588a6572a88518d8816abcb12 (diff)
* nix-store, nix-instantiate: added an option `--add-root' to
  immediately add the result as a permanent GC root.  This is the only
  way to prevent a race with the garbage collector.  For instance, the
  old style

    ln -s $(nix-store -r $(nix-instantiate foo.nix)) \
      /nix/var/nix/gcroots/result

  has two time windows in which the garbage collector can interfere
  (by GC'ing the derivation and the output, respectively).  On the
  other hand,

    nix-store --add-root /nix/var/nix/gcroots/result -r \
      $(nix-instantiate --add-root /nix/var/nix/gcroots/drv \
        foo.nix)

  is safe.

* nix-build: use `--add-root' to prevent GC races.

Diffstat (limited to 'src/nix-instantiate/main.cc')
-rw-r--r--src/nix-instantiate/main.cc34
1 files changed, 27 insertions, 7 deletions
diff --git a/src/nix-instantiate/main.cc b/src/nix-instantiate/main.cc
index 0deaab36d0..7d12c201fb 100644
--- a/src/nix-instantiate/main.cc
+++ b/src/nix-instantiate/main.cc
@@ -3,6 +3,7 @@
 
 #include "globals.hh"
 #include "build.hh"
+#include "gc.hh"
 #include "shared.hh"
 #include "eval.hh"
 #include "parser.hh"
@@ -26,6 +27,14 @@ static Expr evalStdin(EvalState & state, bool parseOnly)
 }
 
 
+static Path gcRoot;
+static int rootNr = 0;
+
+
+/* Print out the paths of the resulting derivation(s).  If the user
+   specified the `--add-root' flag, we register the derivation as a
+   garbage collection root and print out the path of the GC root
+   symlink instead. */
 static void printDrvPaths(EvalState & state, Expr e)
 {
     ATermList es;
@@ -37,7 +46,13 @@ static void printDrvPaths(EvalState & state, Expr e)
         if (a && evalString(state, a) == "derivation") {
             a = queryAttr(e, "drvPath");
             if (a) {
-                cout << format("%1%\n") % evalPath(state, a);
+                Path drvPath = evalPath(state, a);
+                if (gcRoot == "")
+                    printGCWarning();
+                else
+                    drvPath = addPermRoot(drvPath,
+                        makeRootName(gcRoot, rootNr));
+                cout << format("%1%\n") % drvPath;
                 return;
             }
             throw Error("bad derivation");
@@ -77,10 +92,10 @@ void run(Strings args)
     bool evalOnly = false;
     bool parseOnly = false;
 
-    for (Strings::iterator it = args.begin();
-         it != args.end(); )
+    for (Strings::iterator i = args.begin();
+         i != args.end(); )
     {
-        string arg = *it++;
+        string arg = *i++;
 
         if (arg == "-")
             readStdin = true;
@@ -92,6 +107,11 @@ void run(Strings args)
             readOnlyMode = true;
             parseOnly = evalOnly = true;
         }
+        else if (arg == "--add-root") {
+            if (i == args.end())
+                throw UsageError("`--add-root requires an argument");
+            gcRoot = *i++;
+        }
         else if (arg[0] == '-')
             throw UsageError(format("unknown flag `%1%`") % arg);
         else
@@ -105,10 +125,10 @@ void run(Strings args)
         printResult(state, e, evalOnly);
     }
 
-    for (Strings::iterator it = files.begin();
-         it != files.end(); it++)
+    for (Strings::iterator i = files.begin();
+         i != files.end(); i++)
     {
-        Expr e = evalFile(state, absPath(*it));
+        Expr e = evalFile(state, absPath(*i));
         /* !!! parseOnly ignored */
         printResult(state, e, evalOnly);
     }