⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 siglib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
* This routine waits until one of the signals specified in <pSet> is delivered* to the calling thread. It then stores the number of the signal received in* the the location pointed to by <pSig>.** The signals in <pSet> must not be ignored on entrance to sigwait().* If the delivered signal has a signal handler function attached, that* function is not called.** RETURNS: OK, or ERROR on failure.** SEE ALSO: sigtimedwait()*/ int sigwait    (    const sigset_t *pSet,    int *pSig    )    {    struct siginfo info;     if (sigtimedwait(pSet, &info, (struct timespec *)NULL) == ERROR)        return(ERROR);     *pSig = info.si_signo;    return(OK);    }/********************************************************************************** sigvec - install a signal handler** This routine binds a signal handler routine referenced by <pVec> to a* specified signal <sig>.  It can also be used to determine which handler,* if any, has been bound to a particular signal:  sigvec() copies current* signal handler information for <sig> to <pOvec> and does not install a* signal handler if <pVec> is set to NULL (0).** Both <pVec> and <pOvec> are pointers to a structure of type \f3struct* sigvec\fP.  The information passed includes not only the signal handler* routine, but also the signal mask and additional option bits.  The* structure `sigvec' and the available options are defined in signal.h.** RETURNS: OK (0), or ERROR (-1) if the signal number is invalid or the* signal TCB cannot be allocated.** ERRNO: EINVAL, ENOMEM*/int sigvec    (    int			sig,	/* signal to attach handler to */    const struct sigvec	*pVec,	/* new handler information */    struct sigvec	*pOvec	/* previous handler information */    )    {    struct sigaction act, oact;    int retVal;    if (pVec != NULL)	{	act.sa_handler = pVec->sv_handler;	act.sa_mask = pVec->sv_mask;	act.sa_flags = pVec->sv_flags;	retVal = sigaction(sig, &act, &oact);	}    else	retVal = sigaction(sig, NULL, &oact);    if (pOvec != NULL)	{	pOvec->sv_handler = oact.sa_handler;	pOvec->sv_mask = oact.sa_mask;	pOvec->sv_flags = oact.sa_flags;	}    return (retVal);    }/********************************************************************************* sigreturn - early return from a signal handler** NOMANUAL**/void sigreturn    (    struct sigcontext	*pContext    )    {    (void) sigprocmask (SIG_SETMASK, &pContext->sc_mask, 0);    _sigCtxLoad (&pContext->sc_regs);    }/********************************************************************************* sigsetmask - set the signal mask** This routine sets the calling task's signal mask to a specified value.* A one (1) in the bit mask indicates that the specified signal is blocked* from delivery.  Use the macro SIGMASK to construct the mask for a specified* signal number.** RETURNS: The previous value of the signal mask.** SEE ALSO: sigprocmask()*/ int sigsetmask    (    int			mask	/* new signal mask */    )    {    sigset_t in;    sigset_t out;    in = (sigset_t) mask;    (void) sigprocmask (SIG_SETMASK, &in, &out);    return ((int) out);    }/********************************************************************************* sigblock - add to a set of blocked signals** This routine adds the signals in <mask> to the task's set of blocked signals.* A one (1) in the bit mask indicates that the specified signal is blocked* from delivery.  Use the macro SIGMASK to construct the mask for a specified* signal number.** RETURNS: The previous value of the signal mask.** SEE ALSO: sigprocmask()*/ int sigblock    (    int			mask	/* mask of additional signals to be blocked */    )    {    sigset_t in;    sigset_t out;    in = (sigset_t) mask;    (void) sigprocmask (SIG_BLOCK, &in, &out);    return ((int) out);    }/********************************************************************************* raise - send a signal to the caller's task** This routine sends the signal <signo> to the task invoking the call.** RETURNS: OK (0), or ERROR (-1) if the signal number or task ID is invalid.** ERRNO: EINVAL*/int raise    (    int			signo	/* signal to send to caller's task */    )    {    return (kill ((int) taskIdCurrent, signo));    }/********************************************************************************* kill - send a signal to a task (POSIX)** This routine sends a signal <signo> to the task specified by <tid>.** RETURNS: OK (0), or ERROR (-1) if the task ID or signal number is invalid.** ERRNO: EINVAL*/int kill    (    int			tid,	/* task to send signal to */    int			signo	/* signal to send to task */    )    {    if (!issig (signo))	{	errnoSet (EINVAL);	return (ERROR);	}#ifdef WV_INSTRUMENTATION    /* windview - level 1 event logging */    EVT_OBJ_SIG (EVENT_KILL , 2, signo, tid);#endif    if (kernelState || (INT_CONTEXT () && (int) taskIdCurrent == tid))	{	if (TASK_ID_VERIFY (tid) != OK)	    {	    errnoSet (EINVAL);	    return (ERROR);	    }	excJobAdd ((VOIDFUNCPTR) kill, tid, signo, 0, 0, 0, 0);	return (OK);	}    kernelState = TRUE;				/* KERNEL ENTER */     if (TASK_ID_VERIFY (tid) != OK)		/* verify task */	{	windExit ();				/* KERNEL EXIT */	errnoSet (EINVAL);	return (ERROR);	}    sigWindKill ((WIND_TCB *) tid, signo);	/* send signal */     windExit ();				/* KERNEL EXIT */     return (OK);    }/********************************************************************************* sigqueue - send a queued signal to a task* * The function sigqueue() sends the signal specified by <signo> with* the signal-parameter value specified by <value> to the process* specified by <tid>.** RETURNS: OK (0), or ERROR (-1) if the task ID or signal number is invalid,* or if there are no queued-signal buffers available.** ERRNO: EINVAL EAGAIN*/int sigqueue    (    int			tid,    int			signo,    const union sigval	value    )    {    struct sigpend pend;    if (!issig (signo))	{	errnoSet (EINVAL);	return (ERROR);	}#ifdef WV_INSTRUMENTATION    /* windview - level 1 event logging */    EVT_OBJ_SIG (EVENT_KILL , 2, signo, tid);#endif    if (kernelState || (INT_CONTEXT () && (int) taskIdCurrent == tid))	{	if (TASK_ID_VERIFY (tid) != OK)	    {	    errnoSet (EINVAL);	    return (ERROR);	    }	if (_pSigQueueFreeHead == NULL)	    {	    errnoSet (EAGAIN);	    return (ERROR);	    }	excJobAdd ((VOIDFUNCPTR)sigqueue, tid, signo, value.sival_int, 0, 0, 0);	return (OK);	}    kernelState = TRUE;				/* KERNEL ENTER */     if (TASK_ID_VERIFY (tid) != OK)		/* verify task */	{	windExit ();				/* KERNEL EXIT */	errnoSet (EINVAL);	return (ERROR);	}    if (_pSigQueueFreeHead == NULL)	{	windExit ();				/* KERNEL EXIT */	errnoSet (EAGAIN);	return (ERROR);	}    sigPendInit (&pend);    pend.sigp_info.si_signo = signo;    pend.sigp_info.si_code  = SI_QUEUE;    pend.sigp_info.si_value = value;    sigWindPendKill ((WIND_TCB *) tid, &pend);	/* signal a task */     windExit ();				/* KERNEL EXIT */    return (0);    }/********************************************************************************* sigWrapper - trampoline code to get to users signal handler from kernel**/static void sigWrapper    (    struct sigcontext	*pContext    )    {    int signo = pContext->sc_info.si_signo;    struct sigaction *pAction =	&((taskIdCurrent->pSignalInfo))->sigt_vec[signo];    void (*handler)() = pAction->sa_handler;#ifdef WV_INSTRUMENTATION    /* windview - level 1 event logging */    EVT_OBJ_SIG (EVENT_SIGWRAPPER, 2, signo, taskIdCurrent);#endif    if (pAction->sa_flags & SA_RESETHAND)	(void) signal (signo, SIG_DFL);    if (handler != SIG_DFL && handler != SIG_IGN && handler != SIG_ERR)	{	if (pAction->sa_flags & SA_SIGINFO)	    (*handler) (signo, &pContext->sc_info, pContext);	else	    (*handler) (signo, pContext->sc_info.si_value.sival_int, pContext);	}    sigreturn (pContext);    }/********************************************************************************* sigTcbGet - get the pointer to the signal tcb** Get the pointer to the signal tcb.  If there is no signal tcb, try and* allocate it.**/static struct sigtcb *sigTcbGet (void)    {    WIND_TCB *pTcb = taskIdCurrent;    struct sigtcb *pSigTcb;    int ix;    if (INT_RESTRICT () != OK)	return (NULL);			/* errno was set */    if (pTcb->pSignalInfo != NULL)	return (pTcb->pSignalInfo);    pSigTcb = (struct sigtcb *) taskStackAllot((int) taskIdCurrent,					       sizeof (struct sigtcb));    if (pSigTcb == NULL)	{	errnoSet (ENOMEM);	return (NULL);	}    pTcb->pSignalInfo = pSigTcb;    bzero ((void *) pSigTcb, sizeof (struct sigtcb));    for (ix = 0; ix <= _NSIGS; ix++)	pSigTcb->sigt_qhead[ix].sigq_next = pSigTcb->sigt_qhead[ix].sigq_prev =		&pSigTcb->sigt_qhead[ix];    return (pSigTcb);    }/********************************************************************************* sigPendRun - get a signal from the set of pending signals and run it** NOTE: YOU MUST BE IN THE KERNEL.*/static int sigPendRun    (    struct sigtcb	*pSigTcb    )    {    sigset_t set = ~pSigTcb->sigt_blocked;    struct sigcontext sigCtx;    int signo;    if ((signo = sigPendGet (pSigTcb, &set, &sigCtx.sc_info)) > 0)	{	sigCtx.sc_onstack      = 0;	sigCtx.sc_restart      = 0;	sigCtx.sc_mask         = pSigTcb->sigt_blocked;	pSigTcb->sigt_blocked |= (pSigTcb->sigt_vec[signo].sa_mask |				  sigmask(signo));#if CPU_FAMILY == MC680X0	sigCtx.sc_fformat      = 0;#endif	windExit ();				/* KERNEL EXIT */	if (_sigCtxSave (&sigCtx.sc_regs) == 0)	    {	    _sigCtxRtnValSet (&sigCtx.sc_regs, 1);	    sigWrapper (&sigCtx);	    }	return (TRUE);	}    return (FALSE);    }/********************************************************************************* sigPendGet - get a signal from the set of pending signals** NOTE: YOU MUST BE IN THE KERNEL.*/static int sigPendGet    (    struct sigtcb	*pSigTcb,    const sigset_t	*sigset,    struct siginfo 	*info    )    {    long		sig;    long		mask;    struct sigpend	*pSigpend;    mask = *sigset & pSigTcb->sigt_pending;    if (mask == 0)	return (OK);    mask &= -mask;			/* find lowest bit set */    sig = ffsMsb (mask);    if (mask & pSigTcb->sigt_kilsigs)	{	pSigTcb->sigt_kilsigs		&= ~mask;	info->si_signo			= sig;	info->si_code			= SI_KILL;	info->si_value.sival_int	= 0;	}    else	{	pSigpend = structbase(struct sigpend, sigp_q,			      pSigTcb->sigt_qhead[sig].sigq_next);	pSigpend->sigp_q.sigq_prev->sigq_next = pSigpend->sigp_q.sigq_next;	pSigpend->sigp_q.sigq_next->sigq_prev = pSigpend->sigp_q.sigq_prev;	pSigpend->sigp_q.sigq_next = NULL;	pSigpend->sigp_q.sigq_prev = NULL;	*info = pSigpend->sigp_info;	pSigpend->sigp_overruns = pSigpend->sigp_active_overruns;	pSigpend->sigp_active_overruns = 0;	/*	 * free queued signal buffer	 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -