POSIX signal handling versus traditional signal handling

POSIX signal handling versus traditional signal handling

Post by usene » Thu, 25 Aug 2005 08:49:20


I am trying to compare POSIX signal handling with traditional signal
handling. I do see some similarities (posted some sample code to
comp.sources.d), but I see some differences as well. When I say
differences, I mean differences beyond the obvious differences needed
for handling real-time behavior.

For example, in all the code snippets of POSIX Real-time signal
handling that I have seen, I don't see any checks to see if the
signal has been previously set to SIG_IGN, and keeping it that way in
case it has. Also, I don't see the signal handler resetting the
signal, to prevent it from being reset to its default value. Is it
just the code snippets that I am seeing, or are they indeed different?


Thanks,
Gus
 
 
 

POSIX signal handling versus traditional signal handling

Post by Generic Us » Thu, 25 Aug 2005 09:01:45

XXXX@XXXXX.COM wrote:

<snip>

/************************************************************
Traditional Signal handling
************************************************************/
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>

typedef void sigfunc_rt(int);

sigfunc_rt *
sig_install(int signo, sigfunc_rt *func)
{
/* Traditionally the signal handler is installed simply by invoking
signal(int signum, sighandler_t handler); */





/* If the signal has been set to SIG_IGN, keep it that way
This is very helpful, for example, in background jobs, since
background
jobs are supposed to ignore interrupt and quit signals */
sigfunc_rt *sigfunc = SIG_IGN;
if(signal(signo, func) != SIG_IGN)
sigfunc = signal(signo, func);

/* return the pointer to the previously installed signal handler
(as returned by signal) */
return sigfunc;
}


void
sig_handler(int signo)
{
/* When a signal is trapped, it gets reset to its default value ----
hence we need to reset signal() after a signal has been trapped */

signal(signo, sig_handler);
printf("Trapping signal %d\n", signo);

}


int
main()
{
sig_install(SIGINT, sig_handler); /* 2 */
sig_install(SIGQUIT, sig_handler); /* 3 */


for(int i = 0; i < 100; i ++)
{
printf("%s", "#");
fflush(stdout);
sleep(1);
}
exit(0);
}


/************************************************************
POSIX Realtime Signal handling
************************************************************/
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>

typedef void sigfunc_rt(int, siginfo_t *, void *);

sigfunc_rt *
sig_install(int signo, sigfunc_rt *func)
{
sigfunc_rt *sigfunc;

struct sigaction act, oact;

act.sa_sigaction = func; /* must store function addr here */
sigemptyset(&act.sa_mask);
act.sa_flags = SA_SIGINFO; /* must specify this for realtime */

/* if the flag is cleared, the signal handler this is installed
can have the "traditional" signature i.e. void sig_handler(int
signo) */


if (sigaction(signo, &act, &oact) < 0)
{
sigfunc = (sigfunc_rt *) SIG_ERR;
printf("installSigHandle error\n");
}
else
sigfunc = oact.sa_sigaction;

/* return the pointer to the previously installed signal handler
(as returned by sigaction) */

return sigfunc;
}


static void
sig_handler(int signo, siginfo_t *info, void *context)
{
printf("Trapping signal #%d, code = %d, ival = %d\n",
signo, info->si_code, info->si_value.sival_int);
}




int
main(int argc, char **argv)
{
int i, j;
pid_t pid;
sigset_t newset;
union sigval val;

printf("SIGRTMIN = %d, SIGRTMAX = %d\n", (int) SIGRTMIN, (int)
SIGRTMAX);

if ( (pid = fork()) == 0)
{
/* child: block three realtime signals */
sigemptyset(&newset);
sigaddset(&newset, SIGRTMAX);
sigaddset(&newset, SIGRTMAX - 1);
sigaddset(&newset, SIGRTMAX - 2);
sigprocmask(SIG_BLOCK, &newset, NULL);

/* establish signal handler with SA_SIGINFO set */
sig_install(SIGRTMAX, sig_handler);
sig_install(SIGRTMAX - 1, sig_handler);
sig_install(SIGRTMAX - 2, sig_handler);

sleep(6); /* let parent send all the signals */

sigprocmask(SIG_UNBLOCK, &newse
 
 
 

POSIX signal handling versus traditional signal handling

Post by Ulrich Hob » Thu, 25 Aug 2005 16:34:02


AFAIK, BSD and POSIX signals (i.e. everything except ooold Unix V7 or
something) are reliable, so even if you process receives two same
signals in a short timeframe, the behavior will probably be that after
the first handler returns, the second signal is delivered. Old behavior
simply crashed the program, because the signal handler didn't have time
to re-set the handler. I don't know about real-time stuff, though.

--
I believe in Karma. That means I can do bad things to people
all day long and I assume they deserve it.
Dogbert
 
 
 

POSIX signal handling versus traditional signal handling

Post by Maxim Yego » Thu, 25 Aug 2005 17:36:32


???


Under POSIX you can specify if a handler should be reset or left
unchanged using flags using sigaction().
http://www.yqcomputer.com/
 
 
 

POSIX signal handling versus traditional signal handling

Post by Nils Welle » Fri, 26 Aug 2005 01:27:51


Note that in System V, signal() was never fixed, so you still have to
use sigset() (introduced in SVR3), sigaction() or bsd_signal() instead
to get reliable signals - or link with the BSD compatibility library to
make signal() behave like bsd_signal(). The problem is that POSIX leaves
the choice of reset-or-don't-reset after calling signal() up to the
implementation, so System V derivatives continue to do it the way
they've always done it: Don't reset.


No, the second signal will be lost. sigqueue() can send signals with
the semantics you've described, however. Unfortunately, queued signals
are a realtime extension still not provided by FreeBSD/NetBSD/OpenBSD/
MacOS X (and I seem to recall that older Linux implementations do not
support queueing of non-realtime (SIGRTMIN - SIGRTMAX) signals.)

--
Nils R. Weller, Bremen / Germany
My real email address is ``nils<at>gnulinux<dot>nl''
... but I'm not speaking for the Software Libre Foundation!