🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

3 total messages Started by Craig Chamberlain Tue, 22 Dec 1992 16:31
SIGINT handles only once
#5
Author: Craig Chamberlain
Date: Tue, 22 Dec 1992 16:31
162 lines
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
#8
Author: Pat Rankin
Date: Wed, 23 Dec 1992 04:45
36 lines
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
#9
Author: George J. Carrette
Date: Wed, 23 Dec 1992 16:02
27 lines
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