|
Description
|
When an application sets up a signal handler via sigaction(2) and specifies
the SA_SIGINFO flag, it is expecting its signal handler to be called as:
void func(int signo, siginfo_t *info, void *context);
Previous versions of the Posix spec allowed the 'info' parameter
passed to the signal handler to be NULL in certain cases.
This is the way Solaris works when the kernel generates a signal,
for example, when the use types ^C and the kernel sends SIGINT
to the foreground process. In such cases the 'info' parameter
is NULL when the signal handler for SIGINT executes.
The latest (SUSv3) Posix specification has rescinded this.
Now, the 'info' parameter is required always to be non-NULL.
This is the new wording from the SUSv3 spec:
If SA_SIGINFO is set and the signal is caught, the signal-catching function
shall be entered as:
void func(int signo, siginfo_t *info, void *context);
where two additional arguments are passed to the signal-catching function.
The second argument shall point to an object of type siginfo_t explaining the
reason why the signal was generated; the third argument can be cast to a pointer
to an object of type ucontext_t to refer to the receiving process' context that
was interrupted when the signal was delivered.
In the CHANGE HISTORY section of the specification, it states:
In the DESCRIPTION, the second argument to func when SA_SIGINFO is set is no
longer permitted to be NULL, and the description of permitted siginfo_t contents
is expanded by reference to <signal.h>.
So, Solaris Nevada is not in conformance with the latest Posix specification
in this regard.
To put it into conformance for the cases under consideration, the kernel must
arrange to supply a mostly-empty siginfo_t to the signal handler, as is already
done for the sigtimedwait(2) interface:
bzero(infop, sizeof (info));
infop->si_signo = lwp->lwp_cursig;
infop->si_code = SI_NOINFO;
si_signo and si_code are the only two required fields of the siginfo_t structure.
SI_NOINFO marks the sigifo_t structure as having been generated by the kernel
(not, for example, as having been generated via kill(2) from another process).
|
|
Work Around
|
In a signal handler, check for NULL before making reference to
any member of the siginfo pointer. If the siginfo pointer is NULL,
you can be confident that the signal was sent from the kernel, not
from some other process.
|