Thread View: vmsnet.alpha
3 messages
3 total messages
Started by Craig Chamberlain
Tue, 22 Dec 1992 16:31
SIGINT handles only once
Author: Craig Chamberlain
Date: Tue, 22 Dec 1992 16:31
Date: Tue, 22 Dec 1992 16:31
162 lines
3379 bytes
3379 bytes
Here's another signal handling problem I've discovered.
SIGINT, which is for CTRL-C, seems to want to be handled
only once, even though it is reset with a new call to signal()
each occurrence. On the VAX my test program runs fine.
CTRL-C must be hit on the main console three times. On the
Alpha, the first CTRL-C is handled, the second one isn't,
and the third one quietly terminates the program.
If anyone else has encountered these problems or can even duplicate
them, it would be very helpful to me to know that. Email replies
appreciated. (Are other people also experiencing the problems I've
been posting about or am I making a fool of myself with these posts?)
VAX:
$ cc test_sigint.c
$ link test_sigint
$ r test_sigint
ready for 1st test
Cancel
signal handled: sig 2 code -2
SIGINT
ready for 2nd test
Cancel
signal handled: sig 2 code -2
SIGINT
ready for 3rd test
Cancel
signal handled: sig 2 code -2
SIGINT
finished
ALPHA:
$ cc/standard=vaxc/float=ieee_float test_sigint.c
$ link test_sigint
$ r test_sigint
ready for 1st test
Cancel
signal handled: sig 2 code -2
SIGINT
ready for 2nd test
Cancel
Cancel
Here is the code:
/* test_sigint.c */
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <setjmp.h>
#ifndef sigmask
#define sigmask(x) (1 << ((x)-1))
#endif
static void (*save_sigint)();
static jmp_buf env;
static void
e__except()
{
longjmp(env, 1);
}
static void
e__hdwerr (sig, code, scp)
int sig;
int code;
struct sigcontext* scp;
{
/* re-enable the signal that just occurred */
sigsetmask (sigblock (0) & ~sigmask(sig));
if ((int) signal (SIGINT, (void (*)(int)) e__hdwerr) == -1)
printf("error - signal(SIGINT, ...) re-init failed\n");
printf("signal handled: sig %d code %d\n", sig, code);
if (sig == SIGINT)
printf("SIGINT\n");
e__except();
printf("error - execution should not have reached here\n");
} /* e__hdwerr */
void
initialize()
{
save_sigint = signal (SIGINT, (void (*)(int)) e__hdwerr);
if ((int) save_sigint == -1)
printf("signal(SIGINT, ...) failed");
}
int true = 1;
int
main (argc, argv)
int argc;
char *argv [];
{
initialize();
if (setjmp(env) == 0) {
printf("ready for 1st test\n");
while (true)
;
}
else {
if (setjmp(env) == 0) {
printf("ready for 2nd test\n");
while (true)
;
}
else {
if (setjmp(env) == 0) {
printf("ready for 3rd test\n");
while (true)
;
}
else
printf("finished\n");
}
}
} /* main */
--
(My opinions do not necessarily represent those of my employer.)
Craig Chamberlain, Software Engineer, Applicon Schlumberger
Ann Arbor, Michigan chamber@ann-arbor.applicon.slb.com (313) 995-6310
Re: SIGINT handles only once
Author: Pat Rankin
Date: Wed, 23 Dec 1992 04:45
Date: Wed, 23 Dec 1992 04:45
36 lines
2213 bytes
2213 bytes
In article <1992Dec22.163159.22768@ann-arbor.applicon.slb.com>,\
chamber@mailhost.aa.cad.slb.com (Craig Chamberlain) writes...
> Here's another signal handling problem I've discovered.
> SIGINT, which is for CTRL-C, seems to want to be handled
> only once, even though it is reset with a new call to signal()
> each occurrence. On the VAX my test program runs fine.
> CTRL-C must be hit on the main console three times. On the
> Alpha, the first CTRL-C is handled, the second one isn't,
> and the third one quietly terminates the program.
You call printf() and then longjmp() out of a signal handler and end
up surprised that there are problems? The surprise I have is that it
seemed to work reliably on the VAX to begin with. You can't portably call
any C library function from a signal handler except signal() itself with
the same signal number, _unless_ the handler was triggered by a call to
raise() (or abort(), but there doesn't seem any way to control it).
I don't know whether or not DEC expects your code to continue
to work as it did on the VAX, because I haven't seen any documentation
describing what sort of portability they've tried to deliver. I'd
rather see portable code handled efficiently than have crippled run-time
behavior in order to accomodate non-portable code such as your example.
Try something like the following for your handler. If it also fails
to reset itself properly, then you've got a legitimate complaint.
#include <signal.h>
volatile sig_atomic_t ctrl_c_count;
void ctrl_c_handler(int sig)
{
ctrl_c_count++;
signal(sig, ctrl_c_handler);
}
Pat Rankin, rankin@eql.caltech.edu
Re: SIGINT handles only once
Author: George J. Carrette
Date: Wed, 23 Dec 1992 16:02
Date: Wed, 23 Dec 1992 16:02
27 lines
1400 bytes
1400 bytes
In article <22DEC199220451474@eql.caltech.edu>, rankin@eql.caltech.edu (Pat Rankin) writes:
> You call printf() and then longjmp() out of a signal handler and end
> up surprised that there are problems?
If he wants to continue to kludge I can assure that the following code
(from SIOD) "works" on Alpha. Possibly it may work because of the
interposed stack frames, but I am also careful to never allow an err_ctrl_c()
call while already inside other calls to the VAXCRTL,
hence the nointerrupt flag. (If you cannot be good, at least be careful).
Note that when this code is run on the Macintosh I am forced to use
the polling technique anyway, because of a lack of interrupt capability.
void handle_sigint(int sig SIG_restargs)
{signal(SIGINT,handle_sigint);
if (nointerrupt == 1) interrupt_differed = 1;
else err_ctrl_c();}
void err_ctrl_c(void)
{err("control-c interrupt");}
void err(char *message)
{nointerrupt = 1;
printf("ERROR: %s\n",message);
longjmp(errjmp,1);}
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads