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);
}
Пример #3
0
/*
	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
}