Re: Signals

Adam D. Bradley (
Tue, 4 Feb 1997 15:48:21 -0500 (EST)

> > > I don't know what POSIX says about this, but the included code snippet
> > > clearly shows that a signal handler using a negative number is allowed
> > > in the existing system. However, kill() with is negative number is NOT
> > > allowed. In other words, we can't ever use the signal handler that we've
> > > set up!!!
> > >
> > > If negative signals were allowed for user signals. We've got as many
> > > as we would ever need!
> >
> > Sorry for my ignorance, but how difficult would it be to add new signals
> > to the linux kernel? SIGUSR3, SIGUSR4 etc.. ?
> It would not be very difficult at all. The main point was that negative
> signals "are supposed to be" for the use of anybody. Only positive
> signals of specific kinds are specified. Now, if kill() didn't trap
> negative signals, I think that they would work!
> If negative signals were allowed, the kernel would not have to "add" any
> "new" ones. It only uses the "defined" ones, which are only numbers....
> and allows other non-specific handlers to be defined by persons in
> user-mode.

The complication is with kernel internals:


struct task_struct {
struct signal_struct *sig;

struct signal_struct {
int count;
struct sigaction action[32];

This imposes a hard limit: no more than 32 signals per process. Unless we
do some funky stuff when allocating signal_struct. What's more, (I think
- flame me gently if I'm wrong ;-) it's a hard-index (ie, signal 9 causes
action[9] etc), so if a syscall allows registering of negative signals,
it's actually allowing a scribble on kernel memory...(worth looking

struct sigaction {
__sighandler_t sa_handler;
sigset_t sa_mask;
unsigned long sa_flags;
void (*sa_restorer)(void);

__sighandler_t is the function pointer, sigset_t is defined as unsigned
long, "at least 32 bits" (flags for 32 defined symbols), sa_flags
similarly. There is no mechanism in place (that I can see) to support
signals besides those numbered 0..32. Now, if sigaction included a
"signal number" variable (signed int signum), and we could re-work the
internals to parse over the signal_struct.action[] array, checking
signal_struct.action[x].signum, then there could be an arbitrary set of 32
signals for a given process. (Of course, 0,9,etc can't be arbitrarily
re-assigned, but still...) Increasing the number of signals isn't
in-and-of itself difficult, but I would want to look over the POSIX spec
(which signal #'s are allowable, etc) to decide how to do it
_efficiently_. As it is, signal_struct takes up 512Bytes (1/2K), up it to
64 signals (1K) and multiply by 100 processes and we start to get
kernel-memory concerns. Perhaps dynamically-sized signal tables?

Just my $0.02...


He feeds on ashes; a deluded mind has led him    Adam Bradley, UNCA Senior
astray, and he cannot deliver himself or say,             Computer Science
"Is there not a lie in my right hand?"   Isaiah 44:20      <><