ramsey@NCoast.ORG (Cedric Ramsey) (09/28/90)
Hello peoplekind. I have a question about the behavior of the
signal function. Firstly, I want to trap the control-c, break,
and other interrupt keys the user may use to stop a program.
I did this by ;
main()
{
signal (SIGINT, (*handler1) ());
signal (SIGQUIT, (*handler2) ());
...
}
But, when I type a control-c the program handles the signal as
expected; however, when I type the control-c a second time the program
doesn't catch it and simply exits.
I don't know what went wrong. Does anybody outthere have any
thoughts or conjectures ? Any input is needed and desired.
Thanks,
Cedric A. Ramsey
Mail: ramsey@ncoast.ORG
pfalstad@bow.Princeton.EDU (Paul John Falstad) (09/28/90)
In article <1990Sep28.120043.17628@NCoast.ORG>, ramsey@NCoast.ORG (Cedric Ramsey) writes: |> Hello peoplekind. I have a question about the behavior of the |> signal function. Firstly, I want to trap the control-c, break, |> and other interrupt keys the user may use to stop a program. |> I did this by ; |> |> main() |> { |> signal (SIGINT, (*handler1) ()); |> signal (SIGQUIT, (*handler2) ()); |> ... |> } |> |> |> But, when I type a control-c the program handles the signal as |> expected; however, when I type the control-c a second time the program |> doesn't catch it and simply exits. I quote from K&R, p. 255: "When a signal 'sig' subsequently occurs, the signal is __restored to its default behavior__; then the signal-handler is called, as if by (*handler)(sig)." The signal handler should reinstall itself before returning. signal() apparently does not act this way in my implementation (SunOS)... Fortunately. -- Here is the address to complain to: pfalstad@phoenix.princeton.edu PLink:HYPNOS GEnie:P.FALSTAD CIS: 70016,1355 That address again, sync@thumper.princeton.edu PLink:OHS738 GEnie:OHS738 CIS: 4128 143 1234 937
subbarao@phoenix.Princeton.EDU (Kartik Subbarao) (09/28/90)
In article <2901@idunno.Princeton.EDU> pfalstad@bow.Princeton.EDU (Paul John Falstad) writes: >In article <1990Sep28.120043.17628@NCoast.ORG>, ramsey@NCoast.ORG (Cedric Ramsey) writes: >|> Hello peoplekind. I have a question about the behavior of the >|> signal function. Firstly, I want to trap the control-c, break, >|> and other interrupt keys the user may use to stop a program. >|> I did this by ; >|> >|> main() >|> { >|> signal (SIGINT, (*handler1) ()); >|> signal (SIGQUIT, (*handler2) ()); >|> ... >|> } >|> >|> >|> But, when I type a control-c the program handles the signal as >|> expected; however, when I type the control-c a second time the program >|> doesn't catch it and simply exits. > >I quote from K&R, p. 255: > >"When a signal 'sig' subsequently occurs, the signal is __restored to its >default behavior__; then the signal-handler is called, as if by (*handler)(sig)." Ahh... But Paul, don't we want to give him the answer to his question? Too many times K & R has been quoted...and yet no real solutions are given. > >The signal handler should reinstall itself before returning. signal() >apparently does not act this way in my implementation (SunOS)... Fortunately. But programming should be PORTABLE, should it not :-) A solution is suggested in "UNIX programming", by some author whom I've forgotten (a Howard SAMS publication). What you should put in your signal handlers (*handler1), (*handler2), is a simple signal(SIGINT, SIG_DFL); /* replace SIGINT by whatever signal you wish to trap */ This will restore the signal to previous status. >-- >Here is the address to complain to: >pfalstad@phoenix.princeton.edu PLink:HYPNOS GEnie:P.FALSTAD CIS: 70016,1355 >That address again, >sync@thumper.princeton.edu PLink:OHS738 GEnie:OHS738 CIS: 4128 143 1234 937 Or a simple "F" to alt.dev.null :-) -Kartik (I need a new .signature -- any suggestions?) subbarao@{phoenix or gauguin}.Princeton.EDU -|Internet kartik@silvertone.Princeton.EDU (NeXT mail) -| SUBBARAO@PUCC.BITNET - Bitnet
pfalstad@dae.Princeton.EDU (Paul John Falstad) (09/28/90)
In article <2905@idunno.Princeton.EDU> subbarao@phoenix.Princeton.EDU (Kartik Subbarao) writes: >In article <2901@idunno.Princeton.EDU> pfalstad@bow.Princeton.EDU (Paul John Falstad) writes: >>In article <1990Sep28.120043.17628@NCoast.ORG>, ramsey@NCoast.ORG (Cedric Ramsey) writes: >>|> main() >>|> { >>|> signal (SIGINT, (*handler1) ()); >>|> signal (SIGQUIT, (*handler2) ()); >>|> ... >>|> } >>|> But, when I type a control-c the program handles the signal as >>|> expected; however, when I type the control-c a second time the program >>|> doesn't catch it and simply exits. >>I quote from K&R, p. 255: >> >>"When a signal 'sig' subsequently occurs, the signal is __restored to its >>default behavior__; then the signal-handler is called, as if by (*handler)(sig)." >Ahh... But Paul, don't we want to give him the answer to his question? Too many >times K & R has been quoted...and yet no real solutions are given. I did answer his question. Oh, sorry, you wanted a code fragment I suppose. Ok: void handler1(whatever) { printf("You're not getting out so easily!\n"); signal(SIGINT,handler1); /* (*handler1) () not necessary */ } This code implements the following sentence. >>The signal handler should reinstall itself before returning. signal() >>apparently does not act this way in my implementation (SunOS)... Fortunately. > >But programming should be PORTABLE, should it not :-) True. Why are you telling me this? My above answer is portable. I was just commenting on the fact that SunOS does not implement signal this way. >What you should put in your signal handlers (*handler1), (*handler2), >is a simple >signal(SIGINT, SIG_DFL); >This will restore the signal to previous status. Thank you! You have just found a portable way to implement the bug that the original poster wanted to fix. Now it doesn't work on nearly ALL implementations of C instead of merely ANSI compliant ones. Next time, read the article before following up to it. >>Here is the address to complain to: >Or a simple "F" to alt.dev.null :-) Why didn't you then? >(I need a new .signature -- any suggestions?) Disclaimer: I have for a long time been suffering from a species of brain injury which I incurred during the rigors of childbirth; and I'd like to conclude by putting my finger up my nose. How's that? ;-) -- Here is the address to complain to: pfalstad@phoenix.princeton.edu PLink:HYPNOS GEnie:P.FALSTAD CIS: 70016,1355 That address again, sync@thumper.princeton.edu PLink:OHS738 GEnie:OHS738 CIS: 4128 143 1234 937
volpe@underdog.crd.ge.com (Christopher R Volpe) (09/29/90)
In article <2905@idunno.Princeton.EDU>, subbarao@phoenix.Princeton.EDU (Kartik Subbarao) writes: |>In article <2901@idunno.Princeton.EDU> pfalstad@bow.Princeton.EDU (Paul John Falstad) writes: |>>In article <1990Sep28.120043.17628@NCoast.ORG>, ramsey@NCoast.ORG (Cedric Ramsey) writes: |>>|> Hello peoplekind. I have a question about the behavior of the |>>|> signal function. Firstly, I want to trap the control-c, break, |>>|> and other interrupt keys the user may use to stop a program. |>>|> I did this by ; |>>|> |>>|> main() |>>|> { |>>|> signal (SIGINT, (*handler1) ()); |>>|> signal (SIGQUIT, (*handler2) ()); |>>|> ... |>>|> } |>>|> |>>|> |>>|> But, when I type a control-c the program handles the signal as |>>|> expected; however, when I type the control-c a second time the program |>>|> doesn't catch it and simply exits. Isn't the above call to signal messed up to begin with? He is INVOKING the handler itself and using the return value as the argument to "signal". Shouldn't he just be passing "handler1" and "handler2", i.e., the *addresses* of the functions? Shouldn't the code read: main() { signal(SIGINT,handler1); signal(SIGQUIT,handler2); } ================== Chris Volpe G.E. Corporate R&D volpecr@crd.ge.com
brad@SSD.CSD.HARRIS.COM (Brad Appleton) (09/29/90)
There is a difference between AT&T and BSD signal calls (that has already been hinted at) that is important to know in this situation: When you set-up a signal handler in the AT&T universe, your handler is only called the very next time that signal is caught and subsequent calls refer back to the default handler unless you reset your handler in the handler-code. When you set up a signal handler in the BSD universe, your handler is called for all subsequent trappings of that signal unless you specifically reset the handler to be something else in the handler-code. The following code fragment might be used to set up a minimal Control-C handler that would be portable accross Unixes (assuming that "att_universe" is #defined for an AT&T system and "ucb_universe" is #defined for a BSD system): #include <stdio.h> #include <signal.h> void ctrl_c_handler() { printf( "\n+++ in ctrl_c_handler() +++\n" ); #ifdef att_universe /* need to reset this handler so we can trap the signal again */ if ( signal( SIGINT, ctrl_c_handler ) < 0 ) perror( "unable to set-up SIGINT handler" ); #endif } main() { if ( signal( SIGINT, ctrl_c_handler ) < 0 ) perror( "unable to set-up SIGINT handler" ); printf( "about to loop forever\n\n" ); while (1); } Anybody know about DOS and/or VMS??? ______________________ "And miles to go before I sleep." ______________________ Brad Appleton brad@travis.ssd.csd.harris.com Harris Computer Systems ...!uunet!hcx1!brad Fort Lauderdale, FL USA ~~~~~~~~~~~~~~~~~~~~ Disclaimer: I said it, not my company! ~~~~~~~~~~~~~~~~~~~
cpcahil@virtech.uucp (Conor P. Cahill) (09/29/90)
In article <1990Sep28.120043.17628@NCoast.ORG> ramsey@NCoast.ORG (Cedric Ramsey) writes: >main() >{ > signal (SIGINT, (*handler1) ()); > signal (SIGQUIT, (*handler2) ()); On initial inspection I would say there was a problem with your call to signal. This is probably due to the fact that you left off some important code. Normally the signal would be used as follows: main() { int handler1(); int handler2(); (void) signal(SIGINT,handler1); (void) signal(SIGQUIT,handler2); Anyway, on to the real problem.... >But, when I type a control-c the program handles the signal as >expected; however, when I type the control-c a second time the program >doesn't catch it and simply exits. To solve this problem you have to know that whenever a signal is caught the action for that signal is automatically reset to the default state. To fix this you must call signal() each time the handler is executed. For example, handler1(sig) int sig; { signal(sig,handler1); . . . -- Conor P. Cahill (703)430-9247 Virtual Technologies, Inc., uunet!virtech!cpcahil 46030 Manekin Plaza, Suite 160 Sterling, VA 22170
cpcahil@virtech.uucp (Conor P. Cahill) (09/29/90)
In article <2901@idunno.Princeton.EDU> pfalstad@bow.Princeton.EDU (Paul John Falstad) writes: > >The signal handler should reinstall itself before returning. Actually the signal handler should reinstall itself immediatly (i.e. the first thing it does) otherwise the receipt during the execution of the handler may cause grief. Even doing it as the first thing in the handler may not be fast enough to ensure that another signal does not interrupt the program. That is why old System V signals should not be used for interprocess communications unless the rate of signals is guarranteed to be low. -- Conor P. Cahill (703)430-9247 Virtual Technologies, Inc., uunet!virtech!cpcahil 46030 Manekin Plaza, Suite 160 Sterling, VA 22170
ramsey@NCoast.ORG (Cedric Ramsey) (09/30/90)
In article <12253@crdgw1.crd.ge.com> volpe@underdog.crd.ge.com (Christopher R Volpe) writes: >In article <2905@idunno.Princeton.EDU>, subbarao@phoenix.Princeton.EDU >(Kartik Subbarao) writes: >|>In article <2901@idunno.Princeton.EDU> pfalstad@bow.Princeton.EDU >(Paul John Falstad) writes: >|>>In article <1990Sep28.120043.17628@NCoast.ORG>, ramsey@NCoast.ORG >(Cedric Ramsey) writes: >|>>|> Hello peoplekind. I have a question about the behavior of the >|>>|> signal function. Firstly, I want to trap the control-c, break, >|>>|> and other interrupt keys the user may use to stop a program. >|>>|> I did this by ; >|>>|> >|>>|> main() >|>>|> { >|>>|> signal (SIGINT, (*handler1) ()); >|>>|> signal (SIGQUIT, (*handler2) ()); >|>>|> ... >|>>|> } >|>>|> >|>>|> >|>>|> But, when I type a control-c the program handles the signal as >|>>|> expected; however, when I type the control-c a second time the program >|>>|> doesn't catch it and simply exits. > >Isn't the above call to signal messed up to begin with? He is INVOKING >the handler itself and using the return value as the argument to >"signal". Shouldn't he just be passing "handler1" and "handler2", i.e., >the *addresses* of the functions? Shouldn't the code read: >main() >{ > signal(SIGINT,handler1); > signal(SIGQUIT,handler2); >} > >================== >Chris Volpe >G.E. Corporate R&D >volpecr@crd.ge.com Oh, i'm sorry, please excuse me. I met to pass a pointer to a function namely, signal(SIGINT, handler1); signal(SIGQUIT, handler2); I was thinking about function prototypes when I goofed there, an ansi c lint checker would have caught it at compile though, but that's okay; I'm willing to take the flame for it; a minimum price for knowledge, hey. Thankyou 4 your support. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Ignorance is the lack of knowledge, now you know ! ;-) %% %% %% %% Cedric A. Ramsey %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%