00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <iomanip>
00029 #include <sstream>
00030 #include <Basics.H>
00031 #include <OS.H>
00032 #include <RegExp.H>
00033 #include <VestaConfig.H>
00034 #include <chars_seq.H>
00035 #include <UniqueId.H>
00036 #include <RunToolClient.H>
00037 #include <SourceOrDerived.H>
00038 #include <VDirSurrogate.H>
00039 #include "PrimRunTool.H"
00040 #include "Expr.H"
00041 #include "ToolDirectoryServer.H"
00042 #include "Err.H"
00043 #include "ListT.H"
00044 #include "Signal.H"
00045 #include "RunToolHost.H"
00046 #include "ThreadData.H"
00047 #include "EvalBasics.H"
00048
00049 using std::ios;
00050 using std::ostream;
00051 using std::ostringstream;
00052 using std::cout;
00053 using std::cin;
00054 using std::cerr;
00055 using std::setw;
00056 using std::setfill;
00057 using std::hex;
00058 using std::dec;
00059 using std::endl;
00060 using std::flush;
00061
00062
00063 static Text codeName("code"),
00064 sigName("signal"),
00065 stowName("stdout_written"),
00066 stewName("stderr_written"),
00067 stdoName("stdout"),
00068 stdeName("stderr"),
00069 rootName("root"),
00070 coreName("dumped_core");
00071
00072 static DepPath rootPath(Text("."));
00073
00074
00075 static const int runToolDepSize = 80;
00076
00077
00078 static const int runToolDirNum = 20;
00079
00080
00081 struct OurClosure {
00082 Binding newstuff;
00083 VestaSource *dir;
00084 ListT<NodeInfo> *nodeList;
00085 bool found_core;
00086 Text dir_path;
00087 };
00088
00089
00090 static Basics::RegExp *core_match_re = 0;
00091
00092
00093
00094 static const char *core_match_re_default = "core(\\.[0-9][0-9]*)?";
00095
00096 extern "C"
00097 {
00098 void core_match_init()
00099 {
00100
00101
00102 if(VestaConfig::is_set("Evaluator", "core_dump_regexp"))
00103 {
00104 try
00105 {
00106 Text pattern =
00107 VestaConfig::get_Text("Evaluator", "core_dump_regexp");
00108 core_match_re = NEW_CONSTR(Basics::RegExp, (pattern));
00109 }
00110 catch(Basics::RegExp::ParseError e)
00111 {
00112 outputMu.lock();
00113 cerr << "Error parsing [Evaluator]core_dump_regexp: "
00114 << e.msg << endl;
00115 outputMu.unlock();
00116
00117 }
00118 catch(VestaConfig::failure f)
00119 {
00120
00121 }
00122 }
00123
00124
00125
00126
00127 if(core_match_re == 0)
00128 {
00129 try
00130 {
00131 core_match_re = NEW_CONSTR(Basics::RegExp, (core_match_re_default));
00132 }
00133 catch(Basics::RegExp::ParseError e)
00134 {
00135 outputMu.lock();
00136 cerr << "Error parsing default core dump regular expression: "
00137 << e.msg << endl;
00138 outputMu.unlock();
00139 }
00140 }
00141 }
00142 }
00143
00144
00145 static bool core_match(Text arc)
00146 {
00147 static pthread_once_t core_match_once = PTHREAD_ONCE_INIT;
00148 pthread_once(&core_match_once, core_match_init);
00149
00150 if(core_match_re != 0) return core_match_re->match(arc);
00151
00152
00153
00154 return false;
00155 }
00156
00157 Text ToolCommandLineAsText(const RunToolArgs &args)
00158 {
00159
00160 Vals vlist = args.command_line->elems;
00161 Text result;
00162 while (!vlist.Null()) {
00163 if(!result.Empty())
00164 {
00165 result += " ";
00166 }
00167 result += ((TextVC*)(vlist.Pop()))->NDS();
00168 }
00169 return result;
00170 }
00171
00172 chars_seq *ConvertVals(ListVC *list) {
00173
00174 Vals vlist = list->elems;
00175 chars_seq *result = NEW_CONSTR(chars_seq, (5, 100));
00176
00177 while (!vlist.Null()) {
00178 result->append(((TextVC*)(vlist.Pop()))->NDS().chars());
00179 }
00180 return result;
00181 }
00182
00183 chars_seq *ConvertEnvVars(BindingVC *b) {
00184
00185 Context c = b->elems;
00186
00187 chars_seq *result = NEW_CONSTR(chars_seq, (10, 20));
00188 while (!c.Null()) {
00189 Assoc a = c.Pop();
00190 Text t(a->name + "=");
00191 t += ((TextVC*)a->val)->NDS();
00192 result->append(t);
00193 }
00194 return result;
00195 }
00196
00197
00198 bool ProcessDirectory(void* cl, VestaSource::typeTag type, Arc arc,
00199 unsigned int index, Bit32 pseudoInode,
00200 ShortId filesid, bool master) {
00201 NodeInfo ni = NEW(nodeinfo);
00202
00203 ni->type = type;
00204 ni->arc = Text(arc);
00205 ni->index = index;
00206 ((OurClosure*)cl)->nodeList->Push(ni);
00207 return true;
00208 }
00209
00210
00211
00212
00213 static inline bool nfs_open_but_deleted_name(Arc arc)
00214 {
00215
00216
00217 if(strncmp(arc, ".nfs", 4) != 0)
00218 {
00219 return false;
00220 }
00221
00222 arc += 4;
00223
00224
00225 while(*arc && isxdigit(*arc))
00226 {
00227 arc++;
00228 }
00229
00230
00231
00232 return (*arc == 0);
00233 }
00234
00235 bool AddToNewStuff(OurClosure *cl, bool look_for_cores, Text label) {
00236 VestaSource *f, *d;
00237 Text name;
00238 TextVC *file;
00239 NodeInfo ni;
00240 OurClosure newcl;
00241 Arc arc;
00242
00243 while(!cl->nodeList->Null()) {
00244 ni = cl->nodeList->Pop();
00245 arc = ni->arc.chars();
00246 name = Text(arc);
00247 try {
00248 switch (ni->type) {
00249 case VestaSource::mutableFile:
00250 case VestaSource::immutableFile:
00251 {
00252 VestaSource::errorCode res = cl->dir->lookup(arc, f);
00253
00254
00255
00256
00257
00258
00259 if((res == VestaSource::notFound) &&
00260 nfs_open_but_deleted_name(arc))
00261 {
00262 break;
00263 }
00264 assert(res == VestaSource::ok);
00265 assert(f->type == VestaSource::mutableFile ||
00266 f->type == VestaSource::immutableFile);
00267 file = NEW_CONSTR(TextVC, (name, f->shortId(), f->fptag));
00268 cl->newstuff = cl->newstuff->AddBindingAssoc(name, file);
00269 if(look_for_cores && core_match(name)) {
00270 char *sid =
00271 SourceOrDerived::shortIdToName(f->shortId(), false);
00272 outputMu.lock();
00273 cerr << label << "Possible core file: "
00274 << cl->dir_path << name << "\n"
00275 << label << "at " << sid << endl;
00276 outputMu.unlock();
00277 delete[] sid;
00278 cl->found_core = true;
00279 }
00280 break;
00281 }
00282 case VestaSource::volatileDirectory:
00283 case VestaSource::immutableDirectory:
00284 case VestaSource::volatileROEDirectory:
00285 {
00286 VestaSource::errorCode res = cl->dir->lookup(arc, d);
00287 assert(res == VestaSource::ok);
00288 assert(d->type == VestaSource::volatileDirectory ||
00289 d->type == VestaSource::immutableDirectory ||
00290 d->type == VestaSource::volatileROEDirectory);
00291 newcl.newstuff = NEW(BindingVC);
00292 newcl.dir = d;
00293 newcl.nodeList = NEW(ListT<NodeInfo>);
00294 newcl.found_core = false;
00295 newcl.dir_path = cl->dir_path + name + "/";
00296 res = d->list(0, ProcessDirectory, &newcl, NULL, true);
00297 assert(res == VestaSource::ok);
00298 bool new_stuff_added = AddToNewStuff(&newcl, look_for_cores, label);
00299 assert(new_stuff_added);
00300 cl->newstuff = cl->newstuff->AddBindingAssoc(name, newcl.newstuff);
00301 cl->found_core = newcl.found_core || cl->found_core;
00302 break;
00303 }
00304 case VestaSource::deleted:
00305
00306
00307 cl->newstuff = cl->newstuff->AddBindingAssoc(name, valFalse);
00308 break;
00309 default:
00310 outputMu.lock();
00311 Error(Text("AddToNewStuff failed, bad type: ") +
00312 IntToText(ni->type) + ".\n");
00313 outputMu.unlock();
00314 return false;
00315 }
00316 } catch (SRPC::failure f) {
00317 outputMu.lock();
00318 Error(Text("AddToNewStuff failed (") + IntToText(f.r) +
00319 "): " + f.msg + ".\n");
00320 outputMu.unlock();
00321 return false;
00322 }
00323 }
00324 return true;
00325 }
00326
00327
00328 Text volatileDirName(const LongId &fsroot)
00329 {
00330 unsigned int index;
00331 (void) fsroot.getParent(&index);
00332 char arc[(sizeof(index) * 2) + 1];
00333 sprintf(arc, "%08x", index);
00334 return VestaConfig::get_Text("Run_Tool", "VolatileRootName") + "/" + arc;
00335 }
00336
00337
00338 Val RunTool(const RunToolArgs &args, VestaSource*& rootForTool) {
00339
00340
00341 rootForTool = NULL;
00342 LongId fsroot;
00343 ostream *report_out, *report_err, *value_out, *value_err;
00344 SourceOrDerived out_sd, err_sd;
00345 ShortId out_sid = NullShortId, err_sid = NullShortId;
00346 bool stdout_cache, stderr_cache, status_cache, signal_cache;
00347 Text stdin_name;
00348
00349 create_tool_directory_server();
00350
00351
00352 chars_seq *argv = ConvertVals(args.command_line);
00353
00354
00355 if (args.stdin_data->Length() != 0) {
00356 ShortId id = args.stdin_data->Sid();
00357 SourceOrDerived sd;
00358 sd.open(id);
00359 stdin_name = VestaConfig::get_Text("Repository", "metadata_root") +
00360 sd.shortIdToName(id);
00361 sd.close();
00362 }
00363
00364
00365 Binding root = (BindingVC*)args.dot->LookupNoDpnd("root");
00366
00367
00368
00369 DirInfo *rootDir = NEW(DirInfo);
00370 rootDir->b = root;
00371 rootDir->path = rootPath;
00372 rootDir->isRoot = true;
00373 rootDir->child_lookup = false;
00374 rootDir->coarseDep = false;
00375 Word rootHandle = GetNewHandle();
00376 DirInfos *dirInfos = NEW(DirInfos);
00377 dirInfos->dirInfoTbl = NEW_CONSTR(DirInfoTbl, (runToolDirNum));
00378 dirInfos->dirInfoTbl->Put(WordKey(rootHandle), rootDir);
00379 dirInfos->dep = NEW_CONSTR(DPaths, (runToolDepSize));
00380 runToolCalls.Put(WordKey(rootHandle>>20), dirInfos);
00381
00382
00383 Text stdout_treatment((args.stdout_treatment)->NDS());
00384 stdout_cache = true;
00385 report_out = NULL;
00386 value_out = NULL;
00387 if (stdout_treatment == "value" ||
00388 stdout_treatment == "report_value") {
00389 try {
00390 out_sid = CreateDerived();
00391 out_sd.open(out_sid, ios::out);
00392 value_out = &out_sd;
00393 } catch (SRPC::failure f) {
00394 outputMu.lock();
00395 Error(Text("RunTool: Cannot create fstream for standard output; ")
00396 + f.msg + ".\n");
00397 outputMu.unlock();
00398 return NEW(ErrorVC);
00399 } catch (SourceOrDerived::Fatal f) {
00400 outputMu.lock();
00401 Error(Text("RunTool: Cannot create fstream for standard output; ")
00402 + f.msg + ".\n");
00403 outputMu.unlock();
00404 return NEW(ErrorVC);
00405 }
00406 if (out_sd.bad()) {
00407 outputMu.lock();
00408 Error(Text("RunTool: Cannot create fstream for standard output; errno = "
00409 + IntToText(errno)));
00410 outputMu.unlock();
00411 return NEW(ErrorVC);
00412 }
00413 }
00414 if (stdout_treatment == "report_nocache" ||
00415 stdout_treatment == "report" ||
00416 stdout_treatment == "report_value") {
00417 stdout_cache = stdout_treatment != "report_nocache";
00418 report_out = &cout;
00419 }
00420
00421
00422 Text stderr_treatment((args.stderr_treatment)->NDS());
00423 stderr_cache = true;
00424 report_err = NULL;
00425 value_err = NULL;
00426 if (stderr_treatment == "value" ||
00427 stderr_treatment == "report_value") {
00428 try {
00429 err_sid = CreateDerived();
00430 err_sd.open(err_sid, ios::out);
00431 value_err = &err_sd;
00432 } catch (SRPC::failure f) {
00433 outputMu.lock();
00434 Error(Text("RunTool: Cannot create fstream for standard err; ")
00435 + f.msg + ".\n");
00436 outputMu.unlock();
00437 return NEW(ErrorVC);
00438 } catch (SourceOrDerived::Fatal f) {
00439 outputMu.lock();
00440 Error(Text("RunTool: Cannot create fstream for standard err; ")
00441 + f.msg + ".\n");
00442 outputMu.unlock();
00443 return NEW(ErrorVC);
00444 }
00445 if (err_sd.bad()) {
00446 outputMu.lock();
00447 Error(Text("RunTool: Cannot create fstream for standard err; errno = "
00448 + IntToText(errno)));
00449 outputMu.unlock();
00450 return NEW(ErrorVC);
00451 }
00452 }
00453 if (stderr_treatment == "report_nocache" ||
00454 stderr_treatment == "report" ||
00455 stderr_treatment == "report_value") {
00456 stderr_cache = stderr_treatment != "report_nocache";
00457 report_err = &cerr;
00458 }
00459
00460
00461 Text status_treatment((args.status_treatment)->NDS());
00462 if (status_treatment == "report_nocache")
00463 status_cache = false;
00464 else {
00465 assert(status_treatment == "report");
00466 status_cache = true;
00467 }
00468
00469
00470 Text signal_treatment((args.signal_treatment)->NDS());
00471 if (signal_treatment == "report_nocache")
00472 signal_cache = false;
00473 else {
00474 assert(signal_treatment == "report");
00475 signal_cache = true;
00476 }
00477
00478
00479 const Text wd((args.wd_name)->NDS());
00480
00481
00482 BindingVC *envVars = (BindingVC*)args.dot->Lookup("envVars");
00483 chars_seq *ev = ConvertEnvVars(envVars);
00484
00485
00486 try {
00487 VestaSource::errorCode err =
00488 VDirSurrogate::createVolatileDirectory(SRPC::this_host().chars(),
00489 toolDirServerIntfName.chars(),
00490 rootHandle, rootForTool, 0,
00491 !args.existing_writable->b);
00492 if (err != VestaSource::ok) {
00493 outputMu.lock();
00494 Error(Text("RunTool: createVolatileDirectory failed (") +
00495 VestaSource::errorCodeString(err) + ".\n");
00496 outputMu.unlock();
00497 return NEW(ErrorVC);
00498 }
00499 } catch (SRPC::failure f) {
00500 outputMu.lock();
00501 Error(Text("RunTool: createVolatileDirectory failed (")
00502 + IntToText(f.r) + "): " + f.msg + ".\n");
00503 outputMu.unlock();
00504 return NEW(ErrorVC);
00505 }
00506 fsroot = rootForTool->longid;
00507
00508
00509 void* handle;
00510 const Text host(RunToolHost(args.platform, args.loc, handle));
00511 const Text label = ThreadLabel();
00512
00513
00514 outputMu.lock();
00515 cout << label << host << ": ";
00516 for (int arg = 0; arg < argv->length(); arg++) {
00517 cout << (*argv)[arg] << " ";
00518 }
00519 cout << endl;
00520 if(getenv("DEBUG_TOOL_DIR_SERVER"))
00521 {
00522
00523
00524
00525 char handle_buff[17];
00526 sprintf(handle_buff, "%016" FORMAT_LENGTH_INT_64 "x", rootHandle);
00527 cout << label << "[tool dir server root handle = "
00528 << handle_buff << "]" << endl
00529 << label << "[root LongId = ";
00530 for(unsigned int i = 0, len = fsroot.length(); i < len; i++)
00531 {
00532 cout << setw(2) << setfill('0') << hex
00533 << (int) (fsroot.value.byte[i] & 0xff);
00534 }
00535 cout << setfill(' ') << dec << "]" << endl
00536 << label << "[root directory name = ";
00537 cout << volatileDirName(fsroot) << "]" << endl;
00538 }
00539 if(pauseBeforeTool) {
00540 cout << label << "Running in " << volatileDirName(fsroot) << "/"
00541 << wd << endl;
00542 cout << label << "Using the following environment variables:"
00543 << endl;
00544 for(int i = 0; i < ev->length(); i++) {
00545 cout << label << "\t" << (*ev)[i] << endl;
00546 }
00547 char enter;
00548 cout << label << "Press Enter to continue...";
00549 cout << flush;
00550 cin.get(enter);
00551 cout << label << "Continuing." << endl;
00552 }
00553 outputMu.unlock();
00554
00555
00556 RunTool::Tool_result r;
00557 try {
00558 r = RunTool::do_it(
00559 host,
00560 argv,
00561 fsroot,
00562 wd,
00563 ev,
00564 report_out,
00565 value_out,
00566 report_err,
00567 value_err,
00568 &outputMu,
00569 label,
00570 stdin_name
00571 );
00572
00573
00574
00575
00576
00577
00578 if (out_sid != NullShortId) { FS::Close(out_sd); }
00579 if (err_sid != NullShortId) { FS::Close(err_sd); }
00580 } catch (SRPC::failure f) {
00581 outputMu.lock();
00582 Error("invoking _run_tool: " + f.msg + "\n");
00583 outputMu.unlock();
00584 if (out_sid != NullShortId) out_sd.close();
00585 if (err_sid != NullShortId) err_sd.close();
00586 RunToolDone(handle);
00587 throw(Evaluator::failure(Text("_run_tool failure"), false));
00588 } catch (FS::Failure f) {
00589
00590 outputMu.lock();
00591 ostringstream l_err_msg;
00592 l_err_msg << "writing standard output/error file:" << endl
00593 << f;
00594 Error(l_err_msg.str());
00595 outputMu.unlock();
00596 RunToolDone(handle);
00597 throw(Evaluator::failure(Text("_run_tool failure"), false));
00598 }
00599 if(pauseAfterTool || (pauseAfterToolSignal && r.sigval) ||
00600 (pauseAfterToolError && r.status)) {
00601 outputMu.lock();
00602 cout << label << "Ran in " << volatileDirName(fsroot) << "/" << wd
00603 << endl;
00604 cout << label << "Used the following environment variables:" << endl;
00605 for(int i = 0; i < ev->length(); i++) {
00606 cout << label << "\t" << (*ev)[i] << endl;
00607 }
00608 cout << label << "Exited with status " << r.status << ", signal "
00609 << r.sigval << endl;
00610 char enter;
00611 cout << label << "Press Enter to continue...";
00612 cout << flush;
00613 cin.get(enter);
00614 cout << label << "Continuing." << endl;
00615 outputMu.unlock();
00616 }
00617 RunToolDone(handle);
00618
00619 OurClosure cl;
00620 cl.newstuff = NEW(BindingVC);
00621 cl.dir = rootForTool;
00622 cl.nodeList = NEW(ListT<NodeInfo>);
00623 cl.found_core = false;
00624 cl.dir_path = "/";
00625
00626 try {
00627 VestaSource::errorCode ok;
00628 ok = rootForTool->list(0, ProcessDirectory, &cl, NULL, true);
00629 if (ok != VestaSource::ok)
00630 throw (SRPC::failure(ok, "problem listing volatile directory"));
00631 ok = rootForTool->makeFilesImmutable(args.fp_content->num);
00632 if (ok != VestaSource::ok)
00633 throw (SRPC::failure(ok,
00634 "problem with making files immutable for volatile directory"));
00635 bool new_stuff_added = AddToNewStuff(&cl, r.dumped_core, label);
00636 assert(new_stuff_added);
00637 } catch (SRPC::failure f) {
00638 outputMu.lock();
00639 Error(Text("RunTool error (") + IntToText(f.r) + "): " + f.msg + ".\n");
00640 outputMu.unlock();
00641 return NEW(ErrorVC);
00642 }
00643 if (r.dumped_core && !cl.found_core) {
00644 outputMu.lock();
00645 cerr << label << "Warning: tool dumped core but couldn't find the file." << endl;
00646 outputMu.unlock();
00647 }
00648
00649 if (r.sigval && !signal_cache) {
00650 if (stopOnError) {
00651 outputMu.lock();
00652 Error(Text("RunTool error: tool terminated with signal ") +
00653 IntToText(r.sigval) + "(" + getSigMsg(r.sigval) + ").\n");
00654 outputMu.unlock();
00655 throw(Evaluator::failure(Text("exiting"), false));
00656 }
00657 }
00658 else if (r.status && !status_cache) {
00659 if (stopOnError) {
00660 outputMu.lock();
00661 Error(Text("RunTool error: tool terminated with non-zero status (") +
00662 IntToText(r.status) + ").\n");
00663 outputMu.unlock();
00664 throw(Evaluator::failure(Text("exiting"), false));
00665 }
00666 }
00667
00668
00669 Context assocs;
00670 assocs.Push(NEW_CONSTR(AssocVC, (rootName, cl.newstuff)));
00671 if (stderr_treatment == "value" || stderr_treatment == "report_value") {
00672 assocs.Push(NEW_CONSTR(AssocVC, (stdeName,
00673 NEW_CONSTR(TextVC, (Text("stderr"), err_sid, args.fp_content->num)))));
00674 }
00675 if (stdout_treatment == "value" || stdout_treatment == "report_value") {
00676 assocs.Push(NEW_CONSTR(AssocVC, (stdoName,
00677 NEW_CONSTR(TextVC, (Text("stdout"), out_sid, args.fp_content->num)))));
00678 }
00679 assocs.Push(NEW_CONSTR(AssocVC,
00680 (stewName, NEW_CONSTR(BooleanVC, (r.stderr_written)))));
00681 assocs.Push(NEW_CONSTR(AssocVC,
00682 (stowName, NEW_CONSTR(BooleanVC, (r.stdout_written)))));
00683 assocs.Push(NEW_CONSTR(AssocVC,
00684 (sigName, NEW_CONSTR(IntegerVC, (r.sigval)))));
00685 assocs.Push(NEW_CONSTR(AssocVC,
00686 (codeName, NEW_CONSTR(IntegerVC, (r.status)))));
00687 assocs.Push(NEW_CONSTR(AssocVC,
00688 (coreName, NEW_CONSTR(BooleanVC, (r.dumped_core)))));
00689
00690 Val result = NEW_CONSTR(BindingVC, (assocs));
00691
00692
00693 result->cacheit = ((!r.sigval || signal_cache) &&
00694 (!r.status || status_cache) &&
00695 (!r.stdout_written || stdout_cache) &&
00696 (!r.stderr_written || stderr_cache) &&
00697 (!(pauseAfterToolSignal && r.sigval)) &&
00698 (!(pauseAfterToolError && r.status)) &&
00699 (!pauseBeforeTool) &&
00700 (!pauseAfterTool) &&
00701
00702
00703
00704 (!r.dumped_core || signal_cache));
00705
00706
00707
00708
00709
00710 runToolCalls.Delete(rootHandle>>20, dirInfos);
00711
00712
00713
00714
00715 DirInfoIter it(dirInfos->dirInfoTbl);
00716 WordKey unused;
00717 DirInfo *dirInfo;
00718 while(it.Next(unused, dirInfo))
00719 if(!dirInfo->child_lookup)
00720 dirInfos->dep->Add(&(dirInfo->path), valTBinding, TypePK);
00721
00722
00723 result->dps = dirInfos->dep;
00724
00725
00726 return result;
00727 }
00728
00729 void DeleteRootForTool(VestaSource* rootForTool) {
00730 bool err = VDirSurrogate::deleteVolatileDirectory(rootForTool);
00731 if (err != VestaSource::ok)
00732 throw (SRPC::failure(err, "problem deleting volatile directory for runtool"));
00733 }
00734
00735 void CreateRootForDeriveds() {
00736 create_tool_directory_server();
00737 VestaSource::errorCode err =
00738 VDirSurrogate::createVolatileDirectory(SRPC::this_host().chars(),
00739 toolDirServerIntfName.chars(),
00740 GetNewHandle(), rootForDeriveds);
00741 if (err != VestaSource::ok) {
00742 throw (SRPC::failure(err, "problem creating volatile directory"));
00743 }
00744 }
00745
00746 void DeleteRootForDeriveds() {
00747 VestaSource::errorCode err = VDirSurrogate::deleteVolatileDirectory(rootForDeriveds);
00748 if (err != VestaSource::ok) {
00749 throw (SRPC::failure(err, "problem deleting volatile directory"));
00750 }
00751 }
00752
00753 ShortId CreateDerived() {
00754 VestaSource* newvs;
00755 static Basics::mutex cdmu;
00756 static int cdcnt = 0;
00757 char arc[32];
00758 cdmu.lock();
00759 sprintf(arc, "%d", cdcnt++);
00760 cdmu.unlock();
00761 VestaSource::errorCode err =
00762 rootForDeriveds->insertMutableFile(arc, NullShortId, true,
00763 NULL,VestaSource::replaceDiff, &newvs);
00764 if (err != VestaSource::ok) {
00765 throw (SRPC::failure(err, "problem creating derived."));
00766 }
00767 ShortId sid = newvs->shortId();
00768 delete newvs;
00769 newvs = NULL;
00770 if (sid == NullShortId) {
00771 outputMu.lock();
00772 Error(Text("Failed to create derived"));
00773 outputMu.unlock();
00774 throw(Evaluator::failure(Text("exiting"), false));
00775 }
00776 return sid;
00777 }
00778
00779 void PrimRunToolInit() {
00780 rootPath.Extend(Text("root"));
00781 RunToolHostInit();
00782 }