aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 5d7140827..d82f5effa 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 9dc8e0cd0..8d410e404 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 2e2857ffc..47a93901f 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 969abe9e0..b71739aed 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 2fa6f7f40..3d025d5f5 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