Re: Signals

Adam D. Bradley (bradley@cs.unca.edu)
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:

linux/include/linux/sched.h:

struct task_struct {
[snip]
struct signal_struct *sig;
[snip]
}

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
into...)

linux/include/asm-i386:
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...

Adam

--
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
        bradley@cs.unca.edu       http://www.cs.unca.edu/~bradley      <><