stern@bnl.ARPA (Eric G. Stern) (08/28/85)
We recently upgraded to VAX11C V2.0, but the documentation ordered in July has yet to be received. However, I took a look at the release notes and got the impression that signals should work more like UNIX signals than they used to. So, I bravely went forth and wrote a program to test it, but I am getting strange results. Here is the program: #include <stdio.h> #include <setjmp.h> #include <signal.h> jmp_buf main_setjmp; main() { int i; int ctrlc(); signal(SIGINT,ctrlc); setjmp(main_setjmp); for(i = 0; i < 1000; ++i) { printf("Value is %d\n",i); } exit(1); } ctrlc() { printf("signal caught\n"); fflush(stdout); signal(SIGINT,ctrlc); longjmp(main_setjmp,-1); return(-1); } The idea is that the program counts up to 1000 unless an interrupt (^C) is received, in which case it starts all over. I get different behavior depending on how I am logged in. If I log in over an Ethernet terminal server and run the program, the first ^C I type seems to have no effect. The second one causes the routine ctrlc to be activated according to the debugger, but no message ever gets printed, and the program terminates after doing nothing for a while. However, if I log in over DECnet with the SET HOST command, the first ^C prints the message and starts the count from 0. Any further ^C behave just like ^Y and the program terminates, again after a second or two. So, why does this happen? Am I doing something wrong? The second question I have is about a program that works, but I don't understand why. This program is taken from the V1.0 VAX11-C documentation. #define SECONDS 5 #include <signal.h> #include <stdio.h> int number_of_alarms = 5; main() { int alarm_action(); signal(SIGALRM,alarm_action); alarm(SECONDS); pause(); return(1); } alarm_action() { printf("alarm, alarm!!, %d alarms\n", number_of_alarms); if(--number_of_alarms > 0) { signal(SIGALRM, alarm_action); alarm(SECONDS); pause(); } return; } This program prints out five messages spaced in five second intervals. I don't understand why this works. In function alarm_action, execution is proceeding at AST level. The pause just executes the SYS$HIBER system service. So, how does any other signal ever get delivered? Won't the process still be at AST level when the next alarm occurs? Also, it appears that function alarm_action is called five times, but only returns once. Shouldn't this mess up the stack? Examination with the debugger reveals that the stack pointer is the same upon each invocation of alarm_action. Where does the signal stack frame go each time? It is clear that what I am looking for is a better understanding of signal implementation in the context of the VMS system. Does the new VAX11-C documentation provide an explanation? From what I have been able to discover, a signal proceeds with an AST call to a library routine, which uses the LIB$SIGNAL call to transfer into the VAX11-C condition handler which then does something? But what? Eric G. Stern Dept. of Physics SUNY StonyBrook StonyBrook, NY 11794 (516) 282-3773 stern@bnl.arpa stern@bnl.bitnet ...!philabs!sbcs!bnl!stern
KVC%cit-vax@engvax.UUCP (08/30/85)
Yeah, I'm having a problem with signals and longjmp as well. In my case, the following simple program doesn't work: ---------------------------------------------------------------------------- #include <stdio.h> #include <setjmp.h> #include <signal.h> jmp_buf buf; alarmtr() { longjmp(buf, 1); } main() { if (setjmp(buf)) { puts("This line should print every 5 secs forever!"); } signal(SIGALRM, alarmtr); alarm(5); pause(); } ---------------------------------------------------------------------------- This program seems to have two problems. First of all, the signal only gets handled once (like in C V1). The program also exhibits some weird behaviour in the pause() call -- it actually manages to exit, which should be impossible. Somehow, the alarm manages to queue 2 wakeup requests, so the second time it goes into pause(), there is an extra wakeup request hanging around and the program wakes up without going to alarmtr and exits to DCL! I have SPR'ed this, but haven't gotten an answer yet (and it's been many weeks). With an infinite loop instead of a pause, it only gets one signal. In C V1, it was documented that longjmp and signals didn't work right, since you were left at AST level and future signals got ignored. This is supposedly fixed in V2, but it doesn't seem to be. For whatever reason, future signals are still ignored after a longjmp out of a signal handler. In V1 I had a work around with a neat little piece of macro that faked an AST dismissal without exiting the AST routine, but that doesn't work in C V2. So, I am stuck with a big piece of code I cannot recompile. Yuck. /Kevin Carosso engvax!kvc @ CIT-VAX.ARPA Hughes Aircraft Co.