From 40274c1f4f763e634dd031f7a6b4ba8ce2de7a82 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 8 Jul 2003 13:22:08 +0000 Subject: * A command to query the paths referenced by an fstate expression. * Use a temporary directory for build actions. --- src/fstate.cc | 148 +++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 96 insertions(+), 52 deletions(-) (limited to 'src/fstate.cc') diff --git a/src/fstate.cc b/src/fstate.cc index 2e3ffd639c56..fa677a257a14 100644 --- a/src/fstate.cc +++ b/src/fstate.cc @@ -1,4 +1,5 @@ #include +#include #include #include @@ -17,17 +18,20 @@ typedef map Environment; -/* Return true iff the given path exists. */ -bool pathExists(const string & path) +class AutoDelete { - int res; - struct stat st; - res = stat(path.c_str(), &st); - if (!res) return true; - if (errno != ENOENT) - throw SysError(format("getting status of %1%") % path); - return false; -} + string path; +public: + + AutoDelete(const string & p) : path(p) + { + } + + ~AutoDelete() + { + deletePath(path); + } +}; /* Run a program. */ @@ -36,9 +40,19 @@ static void runProgram(const string & program, Environment env) /* Create a log file. */ string logFileName = nixLogDir + "/run.log"; /* !!! auto-pclose on exit */ - FILE * logFile = popen(("tee " + logFileName + " >&2").c_str(), "w"); /* !!! escaping */ + FILE * logFile = popen(("tee -a " + logFileName + " >&2").c_str(), "w"); /* !!! escaping */ if (!logFile) - throw SysError(format("unable to create log file %1%") % logFileName); + throw SysError(format("creating log file `%1%'") % logFileName); + + /* Create a temporary directory where the build will take + place. */ + static int counter = 0; + string tmpDir = (format("/tmp/nix-%1%-%2%") % getpid() % counter++).str(); + + if (mkdir(tmpDir.c_str(), 0777) == -1) + throw SysError(format("creating directory `%1%'") % tmpDir); + + AutoDelete delTmpDir(tmpDir); /* Fork a child to build the package. */ pid_t pid; @@ -51,31 +65,8 @@ static void runProgram(const string & program, Environment env) try { /* child */ -#if 0 - /* Try to use a prebuilt. */ - string prebuiltHashS, prebuiltFile; - if (queryDB(nixDB, dbPrebuilts, hash, prebuiltHashS)) { - - try { - prebuiltFile = getFile(parseHash(prebuiltHashS)); - } catch (Error e) { - cerr << "cannot obtain prebuilt (ignoring): " << e.what() << endl; - goto build; - } - - cerr << "substituting prebuilt " << prebuiltFile << endl; - - int res = system(("tar xfj " + prebuiltFile + " 1>&2").c_str()); // !!! escaping - if (WEXITSTATUS(res) != 0) - /* This is a fatal error, because path may now - have clobbered. */ - throw Error("cannot unpack " + prebuiltFile); - - _exit(0); - } -#endif - - // build: + 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 @@ -157,15 +148,7 @@ Hash hashTerm(ATerm t) } -struct RStatus -{ - /* !!! the comparator of this hash should match the semantics of - the file system */ -// map paths; -}; - - -static ATerm termFromHash(const Hash & hash) +ATerm termFromHash(const Hash & hash) { string path = queryPathByHash(hash); ATerm t = ATreadFromNamedFile(path.c_str()); @@ -188,7 +171,7 @@ Hash writeTerm(ATerm t) } -static FState realise(RStatus & status, FState fs) +static FState realise(FState fs) { char * s1, * s2, * s3; Content content; @@ -212,7 +195,7 @@ static FState realise(RStatus & status, FState fs) /* Fall through. */ if (ATmatch(fs, "Include()", &s1)) { - return realise(status, termFromHash(parseHash(s1))); + return realise(termFromHash(parseHash(s1))); } else if (ATmatch(fs, "Path(, , [])", &s1, &content, &refs)) { @@ -227,7 +210,7 @@ static FState realise(RStatus & status, FState fs) /* Realise referenced paths. */ ATermList refs2 = ATempty; while (!ATisEmpty(refs)) { - refs2 = ATinsert(refs2, realise(status, ATgetFirst(refs))); + refs2 = ATinsert(refs2, realise(ATgetFirst(refs))); refs = ATgetNext(refs); } refs2 = ATreverse(refs2); @@ -278,7 +261,7 @@ static FState realise(RStatus & status, FState fs) /* Realise inputs. */ ATermList ins2 = ATempty; while (!ATisEmpty(ins)) { - ins2 = ATinsert(ins2, realise(status, ATgetFirst(ins))); + ins2 = ATinsert(ins2, realise(ATgetFirst(ins))); ins = ATgetNext(ins); } ins2 = ATreverse(ins2); @@ -335,6 +318,67 @@ static FState realise(RStatus & status, FState fs) FState realiseFState(FState fs) { - RStatus status; - return realise(status, fs); + return realise(fs); +} + + +string fstatePath(FState fs) +{ + char * s1, * s2, * s3; + FState e1, e2; + if (ATmatch(fs, "Path(, , [])", &s1, &e1, &e2)) + return s1; + else if (ATmatch(fs, "Derive(, , [], , [])", + &s1, &s2, &e1, &s3, &e2)) + return s3; + else if (ATmatch(fs, "Include()", &s1)) + return fstatePath(termFromHash(parseHash(s1))); + else + return ""; +} + + +typedef set StringSet; + + +void fstateRefs2(FState fs, StringSet & paths) +{ + char * s1, * s2, * s3; + FState e1, e2; + ATermList refs, ins; + + if (ATmatch(fs, "Path(, , [])", &s1, &e1, &refs)) { + paths.insert(s1); + + while (!ATisEmpty(refs)) { + fstateRefs2(ATgetFirst(refs), paths); + refs = ATgetNext(refs); + } + } + + else if (ATmatch(fs, "Derive(, , [], , [])", + &s1, &s2, &ins, &s3, &e2)) + { + paths.insert(s3); + + while (!ATisEmpty(ins)) { + fstateRefs2(ATgetFirst(ins), paths); + ins = ATgetNext(ins); + } + } + + else if (ATmatch(fs, "Include()", &s1)) + fstateRefs2(termFromHash(parseHash(s1)), paths); + + else throw badTerm("bad fstate expression", fs); +} + + +Strings fstateRefs(FState fs) +{ + StringSet paths; + fstateRefs2(fs, paths); + Strings paths2(paths.size()); + copy(paths.begin(), paths.end(), paths2.begin()); + return paths2; } -- cgit 1.4.1