Thread: how to let my program responds to CTRL+C (linux machine)

  1. #1
    Registered User
    Join Date
    Dec 2008
    Posts
    48

    how to let my program responds to CTRL+C (linux machine)

    My code is basically a infinte loop, I can check a preset time to terminate it, and call final reporting routine. however it is more convenient for me to press CTRL+C, if the code can still call the final reporting routine. Please kindly let me the tricks. Thanks.

    Michael

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Set up a signal handler for SIGTERM, and in the signal handler, set a flag that you check inside your infinite loop, and when the flag is set, call your final report and exit the program.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    shouldn't it be SIGINT?
    And I think the end-the-loop-flag must be declared volatile because it is chanced from outside the context of the process.

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by pheres View Post
    shouldn't it be SIGINT?
    And I think the end-the-loop-flag must be declared volatile because it is chanced from outside the context of the process.
    Yes, true. Too late in the evening here...

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Dec 2008
    Posts
    48
    hey, a example or link? I have no idea how to setup a handler for SIGINT. Thanks!

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Registered User
    Join Date
    Dec 2008
    Posts
    48
    hey, thanks. I googled a few pages. this one, IPC:Interrupts and Signals: <signal.h>, as it is written does not terminate itself. I updated it with the volatile variable suggested in the previous post. the program responds to ctrl+c or ctrl+\ by printing out a message, however it doesn't terminate. please give me a hint. thanks.
    Code:
    #include <stdio.h>
    #include <signal.h>
    #include <iostream>
    #include <iomanip>
    #include <sstream>
    #include <fstream>
    using namespace std;
    void sigproc(int);
    
    void quitproc(int);
    
    volatile bool signaled;
    int main() {
    	signal(SIGINT, sigproc	);
    	signal(SIGQUIT, quitproc);
    	cout << "ctrl-c disabled use ctrl-\\ to quit" << endl;
    	bool signaled = false;
    	for (;;){
    		if (signaled) break;
    	}
    		; /* infinite loop */
    }
    
    void sigproc(int param) {
    	signal(SIGINT, sigproc); /*  */
    	/* NOTE some versions of UNIX will reset signal to default
    	 after each call. So for portability reset signal each time */
    	cout << "you have pressed ctrl-c" << endl;
    
    }
    
    void quitproc(int param) {
    	cout << "ctrl-\\ pressed to quit" << endl;
    	return; /* normal exit status */
    	signaled = true;
    }
    ouptut:
    Code:
    ctrl-c disabled use ctrl-\ to quit
    you have pressed ctrl-c
    you have pressed ctrl-c
    you have pressed ctrl-c
    ctrl-\ pressed to quit
    ctrl-\ pressed to quit
    ctrl-\ pressed to quit
    ctrl-\ pressed to quit
    ctrl-\ pressed to quit
    ctrl-\ pressed to quit
    ctrl-\ pressed to quit
    p.s. the comment in the sigproc() is from the website listed above, it seems conflicts with the example on this page: signal - C++ Reference, which is convoluted. anyone can explain to me? Thanks!

  8. #8
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    You need to call exit() or some such yourself in the signal handler. The default signal handler terminates the program, but you are using your own.

  9. #9
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by cyberfish View Post
    You need to call exit() or some such yourself in the signal handler. The default signal handler terminates the program, but you are using your own.
    An arguably more common way - depending on needs of the program - is for the new signal handler to call the original one. This is readily facilitated, as signal() returns the previous signal handler.

    It is actually good practice, particularly in libraries, to do this: library writers cannot predict all needs of applications that use the library.

    Of course, that logic isn't necessarily applicable for an application that is seeking to disable the effects of CTRL-C.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  10. #10
    Registered User
    Join Date
    Dec 2008
    Posts
    48
    I changed the line from
    Code:
    		if (signaled) break;
    to
    Code:
    		if (signaled) exit(0);
    but it doesn't quit neither.

  11. #11
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    1.
    Code:
    	return; /* normal exit status */
    	signaled = true;
    Code:
    signaled = true;
    is never executed.

    2.
    Code:
    volatile bool signaled;
    int main() {
    	signal(SIGINT, sigproc	);
    	signal(SIGQUIT, quitproc);
    	cout << "ctrl-c disabled use ctrl-\\ to quit" << endl;
    	bool signaled = false;
    ...
    In the loop you are checking this "signaled", not the global one.

  12. #12
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by grumpy View Post
    An arguably more common way - depending on needs of the program - is for the new signal handler to call the original one. This is readily facilitated, as signal() returns the previous signal handler.
    The default signal handler is not a function. Yes, if there was a signal handler previously installed, you can call it. But to actually terminate, you still need to call exit().
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  13. #13
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by brewbuck View Post
    The default signal handler is not a function. Yes, if there was a signal handler previously installed, you can call it. But to actually terminate, you still need to call exit().
    Strictly speaking, that depends on implementation. However, in practice, the implementation in which the original signal is not callable (and not returned from signal() the first time around) is rare. In any event, such a case would be detectable as the return from signal() will either be NULL or be SIG_ERR (with a suitable value of errno set). Otherwise, practically, such cases could not be managed.

    An alternative, should the original handler not be callable, is for the signal handler to remove itself, rereaise the signal, and then reinstall itself. For example;
    Code:
    typedef void (*handler_function)(int);
    void mysignal (int sig)
    {
         
           /*   Whatever else is needed */
    
           handler_function handler = signal (sig, SIG_DFL);
           raise (sig);                 /*   This won't return if the default handler terminates  */
           signal(sig, handler);    /*  reinstall the previous handler - presumably ourself! */
    }
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  14. #14
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    By the wording of the standard, you're not allowed to access the volatile bool from the signal handler. It has to be a volatile sigatomic_t. It must not be anything else.

    (In C++0x, you'll be able to access atomics, but that's not yet available.)
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by CornedBee View Post
    By the wording of the standard, you're not allowed to access the volatile bool from the signal handler. It has to be a volatile sigatomic_t. It must not be anything else.

    (In C++0x, you'll be able to access atomics, but that's not yet available.)
    And whilst I agree with the fact that we should encourage standards compliant code, it is quite clear that FOR MOST architectures, there is nothing wrong with using bool, int, char, or just about any other type. The reason the standard is written that way is to support architectures where accessing certain types may cause an exception (which would perhaps lead to another signal being issued, and if that also does the same thing, we have an endless loop of signals [except you'd hope the OS probably prevents that somehow]), which we obviously do not want.

    Certainly, if you want portable code, use sigatomic_t.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Best way to program on Linux?
    By dweenigma in forum Tech Board
    Replies: 22
    Last Post: 05-14-2007, 05:20 AM
  2. running program with arguments (linux)
    By N8760 in forum C++ Programming
    Replies: 2
    Last Post: 01-28-2002, 02:08 PM
  3. How can I debug a program in linux?
    By zahid in forum C Programming
    Replies: 5
    Last Post: 12-11-2001, 10:34 PM
  4. My program, anyhelp
    By @licomb in forum C Programming
    Replies: 14
    Last Post: 08-14-2001, 10:04 PM

Tags for this Thread