about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2003-08-15T12·32+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2003-08-15T12·32+0000
commit555347744d116b0152a04d4fdb08258276d34199 (patch)
treed3331f1ec3b67671d210c0cc0a85d6c709bd4924
parente374dbf89b0ba9a4f5835ef9ac30eda6df1dce6a (diff)
* Derivation expressions now can specify arguments to be passed to the
  builder.  Note that this unfortunately causes all Fix-computed
  hashes to change.

-rw-r--r--src/exec.cc33
-rw-r--r--src/exec.hh5
-rw-r--r--src/fstate.cc33
-rw-r--r--src/fstate.hh3
-rw-r--r--src/normalise.cc2
5 files changed, 56 insertions, 20 deletions
diff --git a/src/exec.cc b/src/exec.cc
index 5d7140827462..d82f5effaaea 100644
--- a/src/exec.cc
+++ b/src/exec.cc
@@ -35,7 +35,8 @@ public:
 
 
 /* Run a program. */
-void runProgram(const string & program, Environment env)
+void runProgram(const string & program, 
+    const Strings & args, const Environment & env)
 {
     /* Create a log file. */
     string logFileName = nixLogDir + "/run.log";
@@ -68,15 +69,25 @@ void runProgram(const string & program, Environment env)
             if (chdir(tmpDir.c_str()) == -1)
                 throw SysError(format("changing into to `%1%'") % tmpDir);
 
-            /* Fill in the environment.  We don't bother freeing
-               the strings, since we'll exec or die soon
-               anyway. */
-            const char * env2[env.size() + 1];
-            int i = 0;
-            for (Environment::iterator it = env.begin();
-                 it != env.end(); it++, i++)
-                env2[i] = (new string(it->first + "=" + it->second))->c_str();
-            env2[i] = 0;
+            /* Fill in the arguments. */
+            const char * argArr[args.size() + 2];
+            const char * * p = argArr;
+            string progName = baseNameOf(program);
+            *p++ = progName.c_str();
+            for (Strings::const_iterator i = args.begin();
+                 i != args.end(); i++)
+                *p++ = i->c_str();
+            *p = 0;
+
+            /* Fill in the environment. */
+            Strings envStrs;
+            const char * envArr[env.size() + 1];
+            p = envArr;
+            for (Environment::const_iterator i = env.begin();
+                 i != env.end(); i++)
+                *p++ = envStrs.insert(envStrs.end(), 
+                    i->first + "=" + i->second)->c_str();
+            *p = 0;
 
             /* Dup the log handle into stderr. */
             if (dup2(fileno(logFile), STDERR_FILENO) == -1)
@@ -87,7 +98,7 @@ void runProgram(const string & program, Environment env)
                 throw SysError("cannot dup stderr into stdout");
 
             /* Execute the program.  This should not return. */
-            execle(program.c_str(), baseNameOf(program).c_str(), 0, env2);
+            execve(program.c_str(), (char * *) argArr, (char * *) envArr);
 
             throw SysError(format("unable to execute %1%") % program);
             
diff --git a/src/exec.hh b/src/exec.hh
index 9dc8e0cd029c..8d410e404383 100644
--- a/src/exec.hh
+++ b/src/exec.hh
@@ -4,6 +4,8 @@
 #include <string>
 #include <map>
 
+#include "util.hh"
+
 using namespace std;
 
 
@@ -12,7 +14,8 @@ typedef map<string, string> Environment;
 
 
 /* Run a program. */
-void runProgram(const string & program, Environment env);
+void runProgram(const string & program, 
+    const Strings & args, const Environment & env);
 
 
 #endif /* !__EXEC_H */
diff --git a/src/fstate.cc b/src/fstate.cc
index 2e2857ffc9f6..47a93901feab 100644
--- a/src/fstate.cc
+++ b/src/fstate.cc
@@ -120,13 +120,19 @@ static bool parseSlice(ATerm t, Slice & slice)
 
 static bool parseDerive(ATerm t, Derive & derive)
 {
-    ATermList outs, ins, bnds;
+    ATermList outs, ins, args, bnds;
     char * builder;
     char * platform;
 
-    if (!ATmatch(t, "Derive([<list>], [<list>], <str>, <str>, [<list>])",
-            &outs, &ins, &builder, &platform, &bnds))
-        return false;
+    if (!ATmatch(t, "Derive([<list>], [<list>], <str>, <str>, [<list>], [<list>])",
+            &outs, &ins, &platform, &builder, &args, &bnds))
+    {
+        /* !!! compatibility -> remove eventually */
+        if (!ATmatch(t, "Derive([<list>], [<list>], <str>, <str>, [<list>])",
+                &outs, &ins, &builder, &platform, &bnds))
+            return false;
+        args = ATempty;
+    }
 
     while (!ATisEmpty(outs)) {
         char * s1, * s2;
@@ -142,6 +148,15 @@ static bool parseDerive(ATerm t, Derive & derive)
     derive.builder = builder;
     derive.platform = platform;
     
+    while (!ATisEmpty(args)) {
+        char * s;
+        ATerm arg = ATgetFirst(args);
+        if (!ATmatch(arg, "<str>", &s))
+            throw badTerm("string expected", arg);
+        derive.args.push_back(s);
+        args = ATgetNext(args);
+    }
+
     while (!ATisEmpty(bnds)) {
         char * s1, * s2;
         ATerm bnd = ATgetFirst(bnds);
@@ -204,6 +219,11 @@ static ATerm unparseDerive(const Derive & derive)
             ATmake("(<str>, <str>)", 
                 i->first.c_str(), ((string) i->second).c_str()));
     
+    ATermList args = ATempty;
+    for (Strings::const_iterator i = derive.args.begin();
+         i != derive.args.end(); i++)
+        args = ATinsert(args, ATmake("<str>", i->c_str()));
+
     ATermList env = ATempty;
     for (StringPairs::const_iterator i = derive.env.begin();
          i != derive.env.end(); i++)
@@ -211,11 +231,12 @@ static ATerm unparseDerive(const Derive & derive)
             ATmake("(<str>, <str>)", 
                 i->first.c_str(), i->second.c_str()));
 
-    return ATmake("Derive(<term>, <term>, <str>, <str>, <term>)",
+    return ATmake("Derive(<term>, <term>, <str>, <str>, <term>, <term>)",
         ATreverse(outs),
         unparseIds(derive.inputs),
-        derive.builder.c_str(),
         derive.platform.c_str(),
+        derive.builder.c_str(),
+        ATreverse(args),
         ATreverse(env));
 }
 
diff --git a/src/fstate.hh b/src/fstate.hh
index 969abe9e0632..b71739aed98a 100644
--- a/src/fstate.hh
+++ b/src/fstate.hh
@@ -36,8 +36,9 @@ struct Derive
 {
     DeriveOutputs outputs;
     FSIds inputs;
-    string builder;
     string platform;
+    string builder;
+    Strings args;
     StringPairs env;
 };
 
diff --git a/src/normalise.cc b/src/normalise.cc
index 2fa6f7f4011c..3d025d5f5aa1 100644
--- a/src/normalise.cc
+++ b/src/normalise.cc
@@ -169,7 +169,7 @@ FSId normaliseFState(FSId id, FSIdSet pending)
 
         /* Run the builder. */
         msg(lvlChatty, format("building..."));
-        runProgram(fs.derive.builder, env);
+        runProgram(fs.derive.builder, fs.derive.args, env);
         msg(lvlChatty, format("build completed"));
         
     } else