Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Signals: signal chaining within handlers

467 views
Skip to first unread message

bal...@nospam.ne.mediaone.net

unread,
Oct 17, 2000, 8:01:35 PM10/17/00
to

Hi. Knowing that sigaction(2) will provide me with the 'old' signal
disposition, if another routine before me inserted a signal handler for say,
SIGPIPE, my sigaction(2) will give me the address of this previously installed
signal handler. So, then, in my signal handler, because I installed my
signal handler after the one that was installed previously, can, or should,
I use the address I recewived from my sigaction(2) call to make a call into
the previous signal handler? I have seen ZERO documentation about this, but
have written a small test program where this does indeed work.

Is this good preactice? With ZERO documentation about this, I must
assume no. But need to inquire about this further.

Attached is the source for a program that implements this signal
chaining within signal handlers. it currently catches SIGPIPE. Compile the
program and send it a SIGPIPE via kill(1) and you can watch both signal
handlers being called within the program.

Any info on good/bad practise is apprecieated.


Thanks, Jim


#include <stdio.h>
#include <sys/signal.h>
#include <sys/siginfo.h>
#include <sys/ucontext.h>

void sighandler(int sig, siginfo_t *sinfo, ucontext_t *cont);
void sighandler2(int sig, siginfo_t *sinfo, ucontext_t *cont);

struct sigaction olddisp, newdisp;

main(int argc, char **argv)
{
int status;

printf("sighandle: %x, sighandler2: %x\n", sighandler, sighandler2);

memset(&newdisp, 0, sizeof(struct sigaction));
newdisp.sa_sigaction = (void*) sighandler;
newdisp.sa_flags = SA_SIGINFO;
status = sigaction(SIGPIPE, &newdisp, &olddisp);

if(status == -1)
{
perror("sigaction");
exit(-1);
}

if(olddisp.sa_handler == SIG_DFL)
printf("sighandler: prev disp = SIG_DFL\n");
else if(olddisp.sa_handler == SIG_IGN)
printf("sighandler: prev disp = SIG_IGN\n");
else
printf("sighandler: prev disp = %x\n", olddisp.sa_handler);

memset(&newdisp, 0, sizeof(struct sigaction));
newdisp.sa_sigaction = sighandler2;
newdisp.sa_flags = SA_SIGINFO;
status = sigaction(SIGPIPE, &newdisp, &olddisp);

if(status == -1)
{
perror("sigaction");
exit(-1);
}

if(olddisp.sa_handler == SIG_DFL)
printf("sighandler2: prev disp = SIG_DFL\n");
else if(olddisp.sa_handler == SIG_IGN)
printf("sighandler2: prev disp = SIG_IGN\n");
else
printf("sighandler2: prev disp = %x\n", olddisp.sa_handler);
printf("sleeping: pid = %d\n", getpid());
sleep(300);
}

void
sighandler(int sig, siginfo_t *sinfo, ucontext_t *cont)
{
printf("Enter: sighandler\n");


printf("Exit: sighandler\n");
}

void
sighandler2(int sig, siginfo_t *sinfo, ucontext_t *cont)
{
printf("Enter: sighandler2\n");

(*olddisp.sa_handler)(sig, sinfo, cont);

printf("Exit: sighandler2\n");
}

---
Jim
balson AT mediaone DOT net

0 new messages