Thread: using signals to pause and unpause a program via terminal

  1. #1
    Registered User
    Join Date
    Jul 2018
    Posts
    16

    using signals to pause and unpause a program via terminal

    I'm writing a program that counts down from a user desired number. it should pause when ctrl-c is pressed and terminated when ctrl-\ is pressed. I cant seem to get it to pause or countdown. Im new to using signals so i may have done it incorectly.

    Code:
    #include <stdbool.h>
    #include <stdio.h>
    #include <termios.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    
    //global variable
    bool cont = true;
    
    
    //signal handling function
    void sigHandler(int signal)
    {
        if(signal == SIGINT)
        {
            printf("pausing");
            cont = false;
        }
        else
        {
            cont = false;
        }
    }
    
    
    int main(int argc, const char * argv[])
    {
        // install the handler
        signal( SIGINT, sigHandler);
        
        //create terminal interface with termio
        struct termios oldTerm;
        struct termios newTerm;
        //Get the attributes of the terminal
        tcgetattr(0, &oldTerm);
        //If wrong number of arguments
        if(argc != 2)
        {
            printf("Wrong number of arguments. ");
        }
        else
        {
            printf("Initiating Countdown.\n");
            //get the Number from argv
            int startNum = atoi(argv[1]);
            //printf("%d", startNum);
            printf("\n");
            newTerm.c_iflag &= ~IXOFF;
            //set terminal attributes to take effect immediatly
            tcsetattr(1, TCSANOW, &newTerm);
            while(cont)
            {
                printf("%d", startNum);
                fflush(stdout);
                printf("\n");
                sleep(1);
            }
        }
        tcsetattr(1,TCSAFLUSH,&oldTerm);
        return 0;
    }
    this is my original code im now modifying to use signals.
    Code:
    #include <stdio.h>
    #include <termios.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    
    int main(int argc, const char * argv[])
    {
        //create terminal interface with termio
        struct termios oldTerm;
        struct termios newTerm;
        //Get the attributes of the terminal
        tcgetattr(0, &oldTerm);
        //If wrong number of arguments
        if(argc != 2)
        {
            printf("Wrong number of arguments. ");
        }
        else
        {
            printf("Initiating Countdown.\n");
            //get the Number from argv
            int startNum = atoi(argv[1]);
            //printf("%d", startNum);
            printf("\n");
            newTerm.c_iflag &= ~IXOFF;
            //Set P to pause countdown
            newTerm.c_cc[VSTOP] = 'p';
            //set U to resume countdown
            newTerm.c_cc[VSTART] = 'u';
            //set terminal attributes to take effect immediatly
            tcsetattr(1, TCSANOW, &newTerm);
            //create buffer for int to char conversion
            //char numToWord[25];
            //setvbuf(stdout, (char *)NULL, _IONBF, 0);
            for(; startNum > 0; startNum--)
            {
                //sprintf(numToWord, "%d", startNum);
                printf("%d", startNum);
                fflush(stdout);
                printf("\n");
                sleep(1);
            }
        }
        tcsetattr(1,TCSAFLUSH,&oldTerm);
        return 0;
    }

  2. #2
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    This pauses and continues with Ctrl-C.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <signal.h>
    #include <unistd.h>
    #include <termios.h>
     
    bool cont = true;
     
    void sigHandler(int sig) {
        if (sig == SIGINT)
            cont ^= true;
        signal(SIGINT, sigHandler); // reinstall handler
    }
     
    int main(int argc, char **argv) {
        if (argc != 2) {
            fprintf(stderr, "Wrong number of arguments.\n");
            return EXIT_FAILURE;
        }
     
        signal(SIGINT, sigHandler);
     
        struct termios oldTerm, newTerm;
        tcgetattr(1, &oldTerm);
        newTerm = oldTerm;        // copy old terminal settings
        newTerm.c_lflag &= ~ECHO; // then make changes
        tcsetattr(1, TCSANOW, &newTerm);
     
        printf("Initiating Countdown.\n");
        int num = atoi(argv[1]);
     
        while (true) {
            while (cont && num > 0) {
                printf("%d\n", num--);
                sleep(1);
            }
     
            if (num <= 0)
                break;
     
            printf("pausing\n");
            while (!cont) {
                sleep(1);
            }
        }
     
        tcsetattr(1, TCSANOW, &oldTerm);
        printf("Done.\n");
        return 0;
    }
    A little inaccuracy saves tons of explanation. - H.H. Munro

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Also bear in mind that signal handlers should only call functions which are async safe.
    signal-safety(7) - Linux manual page
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Jul 2018
    Posts
    16
    Ohhh i see. The nested while loops were throwing me off when i tried to write that portion because i still wanted to keep my for loop despite while loops making more sense. Thank you for linking linux manual page and your help!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 03-31-2015, 05:58 PM
  2. How to make C program to listen to Operating System Signals?
    By halfrobinhood in forum C Programming
    Replies: 2
    Last Post: 09-21-2011, 06:45 AM
  3. Help for C program using processes and signals
    By enimas in forum Linux Programming
    Replies: 2
    Last Post: 12-14-2010, 11:43 AM
  4. how to catch child program using signals
    By ashok449 in forum C Programming
    Replies: 2
    Last Post: 03-02-2009, 12:50 AM
  5. Why won't my program pause?
    By ladysniper in forum C++ Programming
    Replies: 4
    Last Post: 02-13-2006, 03:22 AM

Tags for this Thread