Example #1
0
/*
 * Identify the attribute in <attr_name>.
 *
 * Check if
 *      1) the attribute has been defined already
 *      2) the value count is correct
 *      3) the assign op is appropriate
 *
 * Invoke appropriate parser.
 *
 * This function will return FAILED only if its in the default section
 * and an attribute cannot be ID'd. Otherwise, it returns OK.
 */
static status_e identify_attribute( entry_e entry_type,
                                    struct service_config *scp,
                                    const char *attr_name,
                                    enum assign_op op,
                                    pset_h attr_values )
{
    const struct attribute   *ap ;
    const char         *func = "identify_attribute" ;

    if ( entry_type == SERVICE_ENTRY )
        ap = attr_lookup( service_attributes, attr_name ) ;
    else
        ap = attr_lookup( default_attributes, attr_name ) ;

    if ( ap == NULL )
        return OK;   /* We simply ignore keywords not on the list */

    if ( ! MODIFIABLE( ap ) )
    {
        if ( SC_SPECIFIED( scp, ap->a_id ) )
        {
            parsemsg( LOG_WARNING, func, "Service %s: attribute already set: %s",
                      SC_NAME(scp), attr_name ) ;
            return OK;
        }

        if ( op != SET_EQ )
        {
            parsemsg( LOG_WARNING, func,
                      "Service %s: operator '%s' cannot be used for attribute '%s'",
                      SC_NAME(scp), ( op == PLUS_EQ ) ? "+=" : "-=", attr_name ) ;
            return OK;
        }
    }
    else      /* modifiable attribute */
    {
        /*
         * For the defaults entry, '=' and '+=' have the same meaning
         */
        if ( entry_type == DEFAULTS_ENTRY && op == SET_EQ )
            op = PLUS_EQ ;
    }

    if ( FIXED_VALUES( ap ) &&
            (unsigned)ap->a_nvalues != pset_count( attr_values ) )
    {
        parsemsg( LOG_WARNING, func,
                  "attribute %s expects %d values and %d values were specified",
                  attr_name, ap->a_nvalues, pset_count( attr_values ) ) ;
        return OK;
    }

    if ( (*ap->a_parser)( attr_values, scp, op ) == OK )
    {   /* This is the normal path. */
        SC_SPECIFY( scp, ap->a_id ) ;
    }
    else if ( entry_type == SERVICE_ENTRY )
    {
        parsemsg( LOG_ERR, func,
                  "Error parsing attribute %s - DISABLING SERVICE", attr_name ) ;
        SC_DISABLE( scp );
    }
    /*
     * We are in the default section and an error was detected. At
     * this point, we should terminate since whatever attribute
     * was trying to be specified cannot be propagated.
     */
    else if ( !debug.on )
        return FAILED;

    return OK;
}
Example #2
0
void sys_Dispatch(struct pt_regs * regs, LONG adjust)
{
	struct ExecBase * SysBase = (struct ExecBase *)*(ULONG *)0x04;

	/* Hmm, interrupts are nesting, not a good idea... */
//	if(user_mode(regs)) {
//		return;
//	}
#if 0
	D(bug("In %s!!!\n",__FUNCTION__));
	D(bug("lr_svc=%x, r0=%x, r1=%x, r2=%x, r9=%x, r12=%x, sp=%x, lr=%x, cpsr=%x\n",
	      regs->lr_svc,
	      regs->r0,
	      regs->r1,
	      regs->r2,
	      regs->r9,
	      regs->r12,
	      regs->sp,
	      regs->lr,
	      regs->cpsr));
#endif
	/* Check if a task switch is necessary */
	/* 1. There has to be another task in the ready-list */
	/* 2. The first task in the ready list hast to have the
	      same or higher priority than the currently active task */

	if( SysBase->TaskReady.lh_Head->ln_Succ != NULL /*
	   ((BYTE)SysBase->ThisTask->tc_Node.ln_Pri <=   
	    (BYTE)((struct Task *)SysBase->TaskReady.lh_Head)->tc_Node.ln_Pri ) */
	   )
	{
		/* Check if task switch is possible */
		if( SysBase->TDNestCnt < 0 )
		{
			if( SysBase->ThisTask->tc_State == TS_RUN )
			{
				SysBase->ThisTask->tc_State = TS_READY;
				Reschedule(SysBase->ThisTask);
				SysBase->AttnResched |= 0x8000;
	                }
			else if( SysBase->ThisTask->tc_State == TS_REMOVED )
				SysBase->AttnResched |= 0x8000;
		}
		else
			SysBase->AttnResched |= 0x80;
	} 				                  	     


	/* Has an interrupt told us to dispatch when leaving */
	if (SysBase->AttnResched & 0x8000)
	{
		SysBase->AttnResched &= ~0x8000;

		/* Save registers for this task (if there is one...) */
		if (SysBase->ThisTask && SysBase->ThisTask->tc_State != TS_REMOVED) {
			regs->lr_svc -= adjust; // adjust is 0 or -4
			SaveRegs(SysBase->ThisTask, regs);
		}

		/* Tell exec that we have actually switched tasks... */
		Dispatch ();
//D(bug("DISPATCHER: New task: %s\n",SysBase->ThisTask->tc_Node.ln_Name));

		/* Get the registers of the old task */
		RestoreRegs(SysBase->ThisTask, regs);
		regs->lr_svc += adjust; // adjust is 0 or -4

		/* Make sure that the state of the interrupts is what the task
		   expects.
		*/
		if (SysBase->IDNestCnt < 0)
			SC_ENABLE(regs);
		else
			SC_DISABLE(regs);
#if 0
		D(bug("after: lr_svc=%x, r0=%x, r1=%x, r2=%x, r9=%x, r12=%x, sp=%x, lr=%x, cpsr=%x (adjust=%d)\n",
		      regs->lr_svc,
		      regs->r0,
		      regs->r1,
		      regs->r2,
		      regs->r9,
		      regs->r12,
		      regs->sp,
		      regs->lr,
		      regs->cpsr,
		      adjust));
#endif
		/* Ok, the next step is to either drop back to the new task, or
		   give it its Exception() if it wants one... */

		if (SysBase->ThisTask->tc_Flags & TF_EXCEPT) {
			Disable();
			Exception();
			Enable();
		}


	}

	/* Leave the interrupt. */
}
Example #3
0
void sys_Dispatch(struct pt_regs * regs)
{
	struct ExecBase * SysBase = (struct ExecBase *)*(ULONG *)0x04;

	/* Hmm, interrupts are nesting, not a good idea... */
	if(!user_mode(regs)) {
		return;
	}

	/* Check if a task switch is necessary */
	/* 1. There has to be another task in the ready-list */
	/* 2. The first task in the ready list hast to have the
	      same or higher priority than the currently active task */

	if( SysBase->TaskReady.lh_Head->ln_Succ != NULL  /* &&
	   ((BYTE)SysBase->ThisTask->tc_Node.ln_Pri <=   
	    (BYTE)((struct Task *)SysBase->TaskReady.lh_Head)->tc_Node.ln_Pri )*/
	   )
	{
		/* Check if task switch is possible */
		if( SysBase->TDNestCnt < 0 )
		{
			if( SysBase->ThisTask->tc_State == TS_RUN )
			{
				SysBase->ThisTask->tc_State = TS_READY;
				Reschedule(SysBase->ThisTask);
				SysBase->AttnResched |= 0x8000;
	                }
			else if( SysBase->ThisTask->tc_State == TS_REMOVED )
				SysBase->AttnResched |= 0x8000;
		}
		else
			SysBase->AttnResched |= 0x80;
	} 				                  	     


	/* Has an interrupt told us to dispatch when leaving */
	if (SysBase->AttnResched & 0x8000)
	{
		SysBase->AttnResched &= ~0x8000;

		/* Save registers for this task (if there is one...) */
		if (SysBase->ThisTask && SysBase->ThisTask->tc_State != TS_REMOVED)
			SaveRegs(SysBase->ThisTask, regs);

		/* Tell exec that we have actually switched tasks... */
		Dispatch ();

		/* Get the registers of the old task */
		RestoreRegs(SysBase->ThisTask, regs);
		/* Make sure that the state of the interrupts is what the task
		   expects.
		*/
		if (SysBase->IDNestCnt < 0)
			SC_ENABLE(regs);
		else
			SC_DISABLE(regs);
		/* Ok, the next step is to either drop back to the new task, or
		   give it its Exception() if it wants one... */

		if (SysBase->ThisTask->tc_Flags & TF_EXCEPT)
		{
			Disable();
			Exception();
			Enable();
		}


	}

	/* Leave the interrupt. */
}