VxWorks Reference Manual : Libraries
sigLib - software signal facility library
sigInit( ) - initialize the signal facilities
sigqueueInit( ) - initialize the queued signal facilities
sigemptyset( ) - initialize a signal set with no signals included (POSIX)
sigfillset( ) - initialize a signal set with all signals included (POSIX)
sigaddset( ) - add a signal to a signal set (POSIX)
sigdelset( ) - delete a signal from a signal set (POSIX)
sigismember( ) - test to see if a signal is in a signal set (POSIX)
signal( ) - specify the handler associated with a signal
sigaction( ) - examine and/or specify the action associated with a signal (POSIX)
sigprocmask( ) - examine and/or change the signal mask (POSIX)
sigpending( ) - retrieve the set of pending signals blocked from delivery (POSIX)
sigsuspend( ) - suspend the task until delivery of a signal (POSIX)
pause( ) - suspend the task until delivery of a signal (POSIX)
sigtimedwait( ) - wait for a signal
sigwaitinfo( ) - wait for real-time signals
sigvec( ) - install a signal handler
sigsetmask( ) - set the signal mask
sigblock( ) - add to a set of blocked signals
raise( ) - send a signal to the caller's task
kill( ) - send a signal to a task (POSIX)
sigqueue( ) - send a queued signal to a task
This library provides a signal interface for tasks. Signals are used to alter the flow control of tasks by communicating asynchronous events within or between task contexts. Any task or interrupt service can "raise" (or send) a signal to a particular task. The task being signaled will immediately suspend its current thread of execution and invoke a task-specified "signal handler" routine. The signal handler is a user-supplied routine that is bound to a specific signal and performs whatever actions are necessary whenever the signal is received. Signals are most appropriate for error and exception handling, rather than as a general purpose intertask communication mechanism.
This library has both a BSD 4.3 and POSIX signal interface. The POSIX interface provides a standardized interface which is more functional than the traditional BSD 4.3 interface. The chart below shows the correlation between BSD 4.3 and POSIX 1003.1 functions. An application should use only one form of interface and not intermix them.
POSIX 1003.1b (Real-Time Extensions) also specifies a queued-signal facility that involves four additional routines: sigqueue( ), sigwaitinfo( ), and sigtimedwait( ).
BSD 4.3 POSIX 1003.1 sigmask( ) sigemptyset( ), sigfillset( ), sigaddset( ), sigdelset( ), sigismember( ) sigblock( ) sigprocmask( ) sigsetmask( ) sigprocmask( ) pause( ) sigsuspend( ) sigvec( ) sigaction( ) (none) sigpending( ) signal( ) signal( ) kill( ) kill( ) In many ways, signals are analogous to hardware interrupts. The signal facility provides a set of 31 distinct signals. A signal can be raised by calling kill( ), which is analogous to an interrupt or hardware exception. A signal handler is bound to a particular signal with sigaction( ) in much the same way that an interrupt service routine is connected to an interrupt vector with intConnect( ). Signals are blocked for the duration of the signal handler, just as interrupts are locked out for the duration of the interrupt service routine. Tasks can block the occurrence of certain signals with sigprocmask( ), just as the interrupt level can be raised or lowered to block out levels of interrupts. If a signal is blocked when it is raised, its handler routine will be called when the signal becomes unblocked.
Several routines (sigprocmask( ), sigpending( ), and sigsuspend( )) take sigset_t data structures as parameters. These data structures are used to specify signal set masks. Several routines are provided for manipulating these data structures: sigemptyset( ) clears all the bits in a segset_t, sigfillset( ) sets all the bits in a sigset_t, sigaddset( ) sets the bit in a sigset_t corresponding to a particular signal number, sigdelset( ) resets the bit in a sigset_t corresponding to a particular signal number, and sigismember( ) tests to see if the bit corresponding to a particular signal number is set.
If a task is pended (for instance, by waiting for a semaphore to become available) and a signal is sent to the task for which the task has a handler installed, then the handler will run before the semaphore is taken. When the handler is done, the task will go back to being pended (waiting for the semaphore). If there was a timeout used for the pend, then the original value will be used again when the task returns from the signal handler and goes back to being pended.
Signal handlers are typically defined as:
void sigHandler ( int sig, /* signal number */ ) { ... }In VxWorks, the signal handler is passed additional arguments and can be defined as:
void sigHandler ( int sig, /* signal number */ int code, /* additional code */ struct sigcontext *pSigContext /* context of task before signal */ ) { ... }The parameter code is valid only for signals caused by hardware exceptions. In this case, it is used to distinguish signal variants. For example, both numeric overflow and zero divide raise SIGFPE (floating-point exception) but have different values for code. (Note that when the above VxWorks extensions are used, the compiler may issue warnings.)
Signal handling routines must follow one of two specific formats, so that they may be correctly called by the operating system when a signal occurs.
Traditional signal handlers receive the signal number as the sole input parameter. However, certain signals generated by routines which make up the POSIX Real-Time Extensions (P1003.1b) support the passing of an additional application-specific value to the handler routine. These include signals generated by the sigqueue( ) call, by asynchronous I/O, by POSIX real-time timers, and by POSIX message queues.
If a signal handler routine is to receive these additional parameters, SA_SIGINFO must be set in the sa_flags field of the sigaction structure which is a parameter to the sigaction( ) routine. Such routines must take the following form:
void sigHandler (int sigNum, siginfo_t * pInfo, void * pContext);Traditional signal handling routines must not set SA_SIGINFO in the sa_flags field, and must take the form of:
void sigHandler (int sigNum);
Certain signals, defined below, are raised automatically when hardware exceptions are encountered. This mechanism allows user-defined exception handlers to be installed. This is useful for recovering from catastrophic events such as bus or arithmetic errors. Typically, setjmp( ) is called to define the point in the program where control will be restored, and longjmp( ) is called in the signal handler to restore that context. Note that longjmp( ) restores the state of the task's signal mask. If a user-defined handler is not installed or the installed handler returns for a signal raised by a hardware exception, then the task is suspended and a message is logged to the console.
The following is a list of hardware exceptions caught by VxWorks and delivered to the offending task. The user may include the higher-level header file sigCodes.h in order to access the appropriate architecture-specific header file containing the code value.
Signal Code Exception SIGSEGV NULL bus error SIGBUS BUS_ADDERR address error SIGILL ILL_ILLINSTR_FAULT illegal instruction SIGFPE FPE_INTDIV_TRAP zero divide SIGFPE FPE_CHKINST_TRAP chk trap SIGFPE FPE_TRAPV_TRAP trapv trap SIGILL ILL_PRIVVIO_FAULT privilege violation SIGTRAP NULL trace exception SIGEMT EMT_EMU1010 line 1010 emulator SIGEMT EMT_EMU1111 line 1111 emulator SIGILL ILL_ILLINSTR_FAULT coprocessor protocol violation SIGFMT NULL format error SIGFPE FPE_FLTBSUN_TRAP compare unordered SIGFPE FPE_FLTINEX_TRAP inexact result SIGFPE FPE_FLTDIV_TRAP divide by zero SIGFPE FPE_FLTUND_TRAP underflow SIGFPE FPE_FLTOPERR_TRAP operand error SIGFPE FPE_FLTOVF_TRAP overflow SIGFPE FPE_FLTNAN_TRAP signaling "Not A Number"
Signal Code Exception SIGBUS BUS_INSTR_ACCESS bus error on instruction fetch SIGBUS BUS_ALIGN address error (bad alignment) SIGBUS BUS_DATA_ACCESS bus error on data access SIGILL ILL_ILLINSTR_FAULT illegal instruction SIGILL ILL_PRIVINSTR_FAULT privilege violation SIGILL ILL_COPROC_DISABLED coprocessor disabled SIGILL ILL_COPROC_EXCPTN coprocessor exception SIGILL ILL_TRAP_FAULT(n) uninitialized user trap SIGFPE FPE_FPA_ENABLE floating point disabled SIGFPE FPE_FPA_ERROR floating point exception SIGFPE FPE_INTDIV_TRAP zero divide SIGEMT EMT_TAG tag overflow
Signal Code Exception SIGBUS BUS_UNALIGNED address error (bad alignment) SIGBUS BUS_BUSERR bus error SIGILL ILL_INVALID_OPCODE invalid instruction SIGILL ILL_UNIMPLEMENTED instr fetched from on-chip RAM SIGILL ILL_INVALID_OPERAND invalid operand SIGILL ILL_CONSTRAINT_RANGE constraint range failure SIGILL ILL_PRIVILEGED privilege violation SIGILL ILL_LENGTH bad index to sys procedure table SIGILL ILL_TYPE_MISMATCH privilege violation SIGTRAP TRAP_INSTRUCTION_TRACE instruction trace fault SIGTRAP TRAP_BRANCH_TRACE branch trace fault SIGTRAP TRAP_CALL_TRACE call trace fault SIGTRAP TRAP_RETURN_TRACE return trace fault SIGTRAP TRAP_PRERETURN_TRACE pre-return trace fault SIGTRAP TRAP_SUPERVISOR_TRACE supervisor trace fault SIGTRAP TRAP_BREAKPOINT_TRACE breakpoint trace fault SIGFPE FPE_INTEGER_OVERFLOW integer overflow SIGFPE FST_ZERO_DIVIDE integer zero divide SIGFPE FPE_FLOATING_OVERFLOW floating point overflow SIGFPE FPE_FLOATING_UNDERFLOW floating point underflow SIGFPE FPE_FLOATING_INVALID_OPERATION invalid floating point operation SIGFPE FPE_FLOATING_ZERO_DIVIDE floating point zero divide SIGFPE FPE_FLOATING_INEXACT floating point inexact SIGFPE FPE_FLOATING_RESERVED_ENCODING floating point reserved encoding
Signal Code Exception SIGBUS BUS_TLBMOD TLB modified SIGBUS BUS_TLBL TLB miss on a load instruction SIGBUS BUS_TLBS TLB miss on a store instruction SIGBUS BUS_ADEL address error (bad alignment) on load instr SIGBUS BUS_ADES address error (bad alignment) on store instr SIGSEGV SEGV_IBUS bus error (instruction) SIGSEGV SEGV_DBUS bus error (data) SIGTRAP TRAP_SYSCALL syscall instruction executed SIGTRAP TRAP_BP break instruction executed SIGILL ILL_ILLINSTR_FAULT reserved instruction SIGILL ILL_COPROC_UNUSABLE coprocessor unusable SIGFPE FPE_FPA_UIO, SIGFPE unimplemented FPA operation SIGFPE FPE_FLTNAN_TRAP invalid FPA operation SIGFPE FPE_FLTDIV_TRAP FPA divide by zero SIGFPE FPE_FLTOVF_TRAP FPA overflow exception SIGFPE FPE_FLTUND_TRAP FPA underflow exception SIGFPE FPE_FLTINEX_TRAP FPA inexact operation
Signal Code Exception SIGILL ILL_DIVIDE_ERROR divide error SIGEMT EMT_DEBUG debugger call SIGILL ILL_NON_MASKABLE NMI interrupt SIGEMT EMT_BREAKPOINT breakpoint SIGILL ILL_OVERFLOW INTO-detected overflow SIGILL ILL_BOUND bound range exceeded SIGILL ILL_INVALID_OPCODE invalid opcode SIGFPE FPE_NO_DEVICE device not available SIGILL ILL_DOUBLE_FAULT double fault SIGFPE FPE_CP_OVERRUN coprocessor segment overrun SIGILL ILL_INVALID_TSS invalid task state segment SIGBUS BUS_NO_SEGMENT segment not present SIGBUS BUS_STACK_FAULT stack exception SIGILL ILL_PROTECTION_FAULT general protection SIGBUS BUS_PAGE_FAULT page fault SIGILL ILL_RESERVED (intel reserved) SIGFPE FPE_CP_ERROR coprocessor error SIGBUS BUS_ALIGNMENT alignment check
Signal Code Exception SIGBUS _EXC_OFF_MACH machine check SIGBUS _EXC_OFF_INST instruction access SIGBUS _EXC_OFF_ALIGN alignment SIGILL _EXC_OFF_PROG program SIGBUS _EXC_OFF_DATA data access SIGFPE _EXC_OFF_FPU floating point unavailable SIGTRAP _EXC_OFF_DBG debug exception (PPC403) SIGTRAP _EXC_OFF_INST_BRK inst. breakpoint (PPC603, PPCEC603, PPC604) SIGTRAP _EXC_OFF_TRACE trace (PPC603, PPCEC603, PPC604, PPC860) SIGBUS _EXC_OFF_CRTL critical interrupt (PPC403) SIGILL _EXC_OFF_SYSCALL system call
Signal Code Exception SIGSEGV TLB_LOAD_MISS TLB miss/invalid (load) SIGSEGV TLB_STORE_MISS TLB miss/invalid (store) SIGSEGV TLB_INITITIAL_PAGE_WRITE Initial page write SIGSEGV TLB_LOAD_PROTEC_VIOLATION TLB protection violation (load) SIGSEGV TLB_STORE_PROTEC_VIOLATION TLB protection violation (store) SIGBUS BUS_LOAD_ADDRESS_ERROR Address error (load) SIGBUS BUS_STORE_ADDRESS_ERROR Address error (store) SIGILL ILLEGAL_INSTR_GENERAL general illegal instruction SIGILL ILLEGAL_SLOT_INSTR slot illegal instruction SIGFPE FPE_INTDIV_TRAP integer zero divide
Two signals are provided for application use: SIGUSR1 and SIGUSR2. VxWorks will never use these signals; however, other signals may be used by VxWorks in the future.
Signal Code Exception SIGILL ILL_ILLINSTR_GENERAL general illegal instruction SIGILL ILL_ILLINSTR_SLOT slot illegal instruction SIGBUS BUS_ADDERR_CPU CPU address error SIGBUS BUS_ADDERR_DMA DMA address error SIGFPE FPE_INTDIV_TRAP integer zero divide
signal.h
sigLib, intLib, IEEE POSIX 1003.1b, VxWorks Programmer's Guide: Basic OS
sigInit( ) - initialize the signal facilities
int sigInit (void)
This routine initializes the signal facilities. It is usually called from the system start-up routine usrInit( ) in usrConfig, before interrupts are enabled.
OK, or ERROR if the delete hooks cannot be installed.
S_taskLib_TASK_HOOK_TABLE_FULL
sigqueueInit( ) - initialize the queued signal facilities
int sigqueueInit ( int nQueues )
This routine initializes the queued signal facilities. It must be called before any call to sigqueue( ). It is usually called from the system start-up routine usrInit( ) in usrConfig, after sysInit( ) is called.
It allocates nQueues buffers to be used by sigqueue( ). A buffer is used by each call to sigqueue( ) and freed when the signal is delivered (thus if a signal is block, the buffer is unavailable until the signal is unblocked.)
OK, or ERROR if memory could not be allocated.
sigemptyset( ) - initialize a signal set with no signals included (POSIX)
int sigemptyset ( sigset_t * pSet /* signal set to initialize */ )
This routine initializes the signal set specified by pSet, such that all signals are excluded.
OK (0), or ERROR (-1) if the signal set cannot be initialized.
No errors are detectable.
sigfillset( ) - initialize a signal set with all signals included (POSIX)
int sigfillset ( sigset_t * pSet /* signal set to initialize */ )
This routine initializes the signal set specified by pSet, such that all signals are included.
OK (0), or ERROR (-1) if the signal set cannot be initialized.
No errors are detectable.
sigaddset( ) - add a signal to a signal set (POSIX)
int sigaddset ( sigset_t * pSet, /* signal set to add signal to */ int signo /* signal to add */ )
This routine adds the signal specified by signo to the signal set specified by pSet.
OK (0), or ERROR (-1) if the signal number is invalid.
EINVAL
sigdelset( ) - delete a signal from a signal set (POSIX)
int sigdelset ( sigset_t * pSet, /* signal set to delete signal from */ int signo /* signal to delete */ )
This routine deletes the signal specified by signo from the signal set specified by pSet.
OK (0), or ERROR (-1) if the signal number is invalid.
EINVAL
sigismember( ) - test to see if a signal is in a signal set (POSIX)
int sigismember ( const sigset_t * pSet, /* signal set to test */ int signo /* signal to test for */ )
This routine tests whether the signal specified by signo is a member of the set specified by pSet.
1 if the specified signal is a member of the specified set, OK (0) if it is not, or ERROR (-1) if the test fails.
EINVAL
signal( ) - specify the handler associated with a signal
void (*signal ( int signo, void (*pHandler) () )) ()
This routine chooses one of three ways in which receipt of the signal number signo is to be subsequently handled. If the value of pHandler is SIG_DFL, default handling for that signal will occur. If the value of pHandler is SIG_IGN, the signal will be ignored. Otherwise, pHandler must point to a function to be called when that signal occurs.
The value of the previous signal handler, or SIG_ERR.
sigaction( ) - examine and/or specify the action associated with a signal (POSIX)
int sigaction ( int signo, /* signal of handler of interest */ const struct sigaction * pAct, /* location of new handler */ struct sigaction * pOact /* location to store old handler */ )
This routine allows the calling process to examine and/or specify the action to be associated with a specific signal.
OK (0), or ERROR (-1) if the signal number is invalid.
EINVAL
sigprocmask( ) - examine and/or change the signal mask (POSIX)
int sigprocmask ( int how, /* how signal mask will be changed */ const sigset_t * pSet, /* location of new signal mask */ sigset_t * pOset /* location to store old signal mask */ )
This routine allows the calling process to examine and/or change its signal mask. If the value of pSet is not NULL, it points to a set of signals to be used to change the currently blocked set.
The value of how indicates the manner in which the set is changed and consists of one of the following, defined in signal.h:
- SIG_BLOCK
- the resulting set is the union of the current set and the signal set pointed to by pSet.
- SIG_UNBLOCK
- the resulting set is the intersection of the current set and the complement of the signal set pointed to by pSet.
- SIG_SETMASK
- the resulting set is the signal set pointed to by pSset.
OK (0), or ERROR (-1) if how is invalid.
EINVAL
sigLib, sigsetmask( ), sigblock( )
sigpending( ) - retrieve the set of pending signals blocked from delivery (POSIX)
int sigpending ( sigset_t * pSet /* location to store pending signal set */ )
This routine stores the set of signals that are blocked from delivery and that are pending for the calling process in the space pointed to by pSet.
OK (0), or ERROR (-1) if the signal TCB cannot be allocated.
ENOMEM
sigsuspend( ) - suspend the task until delivery of a signal (POSIX)
int sigsuspend ( const sigset_t * pSet /* signal mask while suspended */ )
This routine suspends the task until delivery of a signal. While suspended, pSet is used as the set of masked signals.
Since the sigsuspend( ) function suspends thread execution indefinitely, there is no successful completion return value.
-1, always.
EINTR
pause( ) - suspend the task until delivery of a signal (POSIX)
int pause (void)
This routine suspends the task until delivery of a signal.
Since the pause( ) function suspends thread execution indefinitely, there is no successful completion return value.
-1, always.
EINTR
sigtimedwait( ) - wait for a signal
int sigtimedwait ( const sigset_t * pSet, /* the signal mask while suspended */ struct siginfo * pInfo, /* return value */ const struct timespec * pTimeout )
The function sigtimedwait( ) selects the pending signal from the set specified by pSet. If multiple signals in pSet are pending, it will remove and return the lowest numbered one. If no signal in pSet is pending at the time of the call, the task will be suspend until one of the signals in pSet become pending, it is interrupted by an unblocked caught signal, or until the time interval specified by pTimeout has expired. If pTimeout is NULL, then the timeout interval is forever.
If the pInfo argument is non-NULL, the selected signal number is stored in the si_signo member, and the cause of the signal is stored in the si_code member. If the signal is a queued signal, the value is stored in the si_value member of pInfo; otherwise the content of si_value is undefined.
The following values are defined in signal.h for si_code:
- SI_USER
- the signal was sent by the kill( ) function.
- SI_QUEUE
- the signal was sent by the sigqueue( ) function.
- SI_TIMER
- the signal was generated by the expiration of a timer set by timer_settime( ).
- SI_ASYNCIO
- the signal was generated by the completion of an asynchronous I/O request.
- SI_MESGQ
- the signal was generated by the arrival of a message on an empty message queue.
The function sigtimedwait( ) provides a synchronous mechanism for tasks to wait for asynchromously generated signals. A task should use sigprocmask( ) to block any signals it wants to handle synchronously and leave their signal handlers in the default state. The task can then make repeated calls to sigtimedwait( ) to remove any signals that are sent to it.
Upon successful completion (that is, one of the signals specified by pSet is pending or is generated) sigtimedwait( ) will return the selected signal number. Otherwise, a value of -1 is returned and errno is set to indicate the error.
- EINTR
- The wait was interrupted by an unblocked, caught signal.
- EAGAIN
- No signal specified by pSet was delivered within the specified timeout period.
- EINVAL
- The pTimeout argument specified a tv_nsec value less than zero or greater than or equal to 1000 million.
sigwaitinfo( ) - wait for real-time signals
int sigwaitinfo ( const sigset_t * pSet, /* the signal mask while suspended */ struct siginfo * pInfo /* return value */ )
The function sigwaitinfo( ) is equivalent to calling sigtimedwait( ) with pTimeout equal to NULL. See that manual entry for more information.
Upon successful completion (that is, one of the signals specified by pSet is pending or is generated) sigwaitinfo( ) returns the selected signal number. Otherwise, a value of -1 is returned and errno is set to indicate the error.
- EINTR
- The wait was interrupted by an unblocked, caught signal.
sigvec( ) - install a signal handler
int sigvec ( int sig, /* signal to attach handler to */ const struct sigvec * pVec, /* new handler information */ struct sigvec * pOvec /* previous handler information */ )
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 struct sigvec. 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.
OK (0), or ERROR (-1) if the signal number is invalid or the signal TCB cannot be allocated.
EINVAL, ENOMEM
sigsetmask( ) - set the signal mask
int sigsetmask ( int mask /* new 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.
The previous value of the signal mask.
sigLib, sigprocmask( )
sigblock( ) - add to a set of blocked signals
int sigblock ( int mask /* mask of additional signals to be blocked */ )
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.
The previous value of the signal mask.
sigLib, sigprocmask( )
raise( ) - send a signal to the caller's task
int raise ( int signo /* signal to send to caller's task */ )
This routine sends the signal signo to the task invoking the call.
OK (0), or ERROR (-1) if the signal number or task ID is invalid.
EINVAL
kill( ) - send a signal to a task (POSIX)
int kill ( int tid, /* task to send signal to */ int signo /* signal to send to task */ )
This routine sends a signal signo to the task specified by tid.
OK (0), or ERROR (-1) if the task ID or signal number is invalid.
EINVAL
sigqueue( ) - send a queued signal to a task
int sigqueue ( int tid, int signo, const union sigval value )
The function sigqueue( ) sends the signal specified by signo with the signal-parameter value specified by value to the process specified by tid.
OK (0), or ERROR (-1) if the task ID or signal number is invalid, or if there are no queued-signal buffers available.
EINVAL EAGAIN