SValue For::Evaluate(const sptr<BShell>& parent, const sptr<ICommand>& shell, bool* outExit) { SVector<SValue> args; for (size_t i = 0 ; i < m_words.CountItems(); i++) { bool insert_args = false; //bout << "WORDS [" << i << "] " << m_words[i] << endl; SValue expanded = Expand(shell, m_words.ItemAt(i), &insert_args); if (insert_args) { collect_arguments(expanded.AsString(), &args); } else { //bout << "adding expanded " << expanded << endl; args.AddItem(expanded); } } *outExit = false; SValue returned = SValue::Status(B_OK); for (size_t i = 0 ; i < args.CountItems() && !*outExit; i++) { //bout << "setting m_condition to be " << args.ItemAt(i) << endl; shell->SetProperty(SValue::String(m_condition), args.ItemAt(i)); returned = m_dolist->Evaluate(parent, shell, outExit); } return returned; }
void add_binder_cleanup_func(binder_cleanup_func func) { SAutolock _l(g_cleanupLock.Lock()); g_cleanupFuncs.AddItem(func); }
/* While it's not possible to actually do it, it's possible to make manifest files that describe a circular dependency of one VM on another, and it's not okay to crash if some mean person does this. So keep a list of vms that we're trying instantiate, and fail if it's cyclical. */ sptr<IBinder> BProcess::DoInstantiate( const SContext& context, const SValue &componentInfo, const SString &component, SVector<SString> &vmIDs, const SValue &args, status_t* outError) { sptr<IBinder> b; SValue v; bool found; size_t i, count; //#if BUILD_TYPE == BUILD_TYPE_DEBUG // SContext default_context = get_default_context(); // if (default_context.AsBinder() != context.AsBinder()) { // // for now, all the shell commands from the bootscript are instantiated // // in the system context. // // Weed those out (and don't do the assert) // SValue shellInterface("org.openbinder.tools.ICommand"); // if (shellInterface != componentInfo["interface"]) { // bout << "WHOA! Instantiating component in System context! (Is this okay?)" << endl; // bout << "... componentInfo = " << componentInfo << endl; // } // } // // DbgOnlyFatalErrorIf(default_context.AsBinder() != context.AsBinder(), "Why are we instantiating in System context?"); // //#endif SValue virtualMachineNameValue = componentInfo["vm"]; // If there is no VM specified, then it's an executable file if (!virtualMachineNameValue.IsDefined()) { const SValue file = componentInfo["file"]; if (!file.IsDefined()) { if (outError) *outError = B_ENTRY_NOT_FOUND; DbgOnlyFatalError("No file found for component"); return NULL; } // Load the image for this package. sptr<ComponentImage> image = get_shared_object(file, componentInfo); // And now, if we found the image, instantiate the requested component, // using the component name, not the full ID. if (image != NULL) { #if BUILD_TYPE == BUILD_TYPE_DEBUG const int32_t origCount = image->StrongCount(); #endif sptr<IBinder> obj = image->InstantiateComponent(componentInfo["local"].AsString(), context, args); #if BUILD_TYPE == BUILD_TYPE_DEBUG const int32_t newCount = image->StrongCount(); if (obj != NULL && newCount <= origCount) { bout << endl << "***********************************************" << endl << "******************* WARNING *******************" << endl << "***********************************************" << endl << "A component MAY not be using SPackageSptr!!!" << endl << "Original image reference count was " << origCount << ", the new count is " << newCount << endl << "The component info is: " << componentInfo << endl << endl; } #endif if (outError) *outError = B_OK; return obj; } if (outError) *outError = B_ERROR; return NULL; } // avoid end-of-non-void-function-not-reached warning /* else */ #if !LIBBE_BOOTSTRAP { SString virtualMachineComponent = virtualMachineNameValue.AsString(); SValue vmComponentInfo; SString vmComponentName; context.LookupComponent(virtualMachineComponent, &vmComponentInfo); // If we found a cycle, fail count = vmIDs.CountItems(); for (i=0; count; i++) { if (vmIDs[i] == virtualMachineComponent) { if (outError) *outError = B_ERROR; return NULL; } } vmIDs.AddItem(virtualMachineComponent); // Get a running vm! m_imageLock.LockQuick(); sptr<IVirtualMachine> vm = m_imageData->vms.ValueFor(virtualMachineComponent, &found); if (!found) { // Oooh. Recursion. Instantiate the virtual machine. // There's no good way of passing args through to the vm also, so pass B_UNDEFINED_VALUE b = this->DoInstantiate(context, vmComponentInfo, vmComponentName, vmIDs, B_UNDEFINED_VALUE, outError); vm = IVirtualMachine::AsInterface(b); ErrFatalErrorIf(vm == NULL, "could not instantiate VM"); m_imageData->vms.AddItem(virtualMachineComponent, vm); vm->Init(); } m_imageLock.Unlock(); // Have the vm instantiate the object return vm->InstantiateComponent(componentInfo, component, args, outError); } #endif }