Search code examples
clinuxunixiosigint

How to mask a signal when I handle a variable in signal _handler and in main function


I am trying to copy the contents from one file to another, with SIGINT the program gets interrupted to print the number of bytes copied. I tried to use the sigprocmask while the flag initialization, flag check, and flag clear to avoid a race condition. But I don't know how to check whether this sigprocmask works or not. I have been trying to find out quite a long time for this.


void signal_handler(int num)
{
    flag = 1;
}
int main()
{
    signal(SIGINT, signal_handler);
    ret = sigaddset(&set, SIGINT);  
     /* Code for 
      * copying the bytes from one file to another
      */
    sigprocmask(SIG_BLOCK, &set, NULL);         
    if (flag == 1)
        printf("The number of bytes copied are :%llu\n", bytes); 
    flag = 0;
    sigprocmask(SIG_UNBLOCK, &set, NULL);
    }
}

Solution

  • It should work as you expect. The only thing you need to ensure is that flag is of type volatile sig_atomic_t to avoid data race on flag.

    Here's an example. The loop prints the value of bytes continuously (it'd wrap around at some point when bytes reaches UINT64_MAX). You can repeatedly send SIGINT to test.

    #include <stdio.h>
    #include <signal.h>
    #include <inttypes.h>
    
    volatile sig_atomic_t flag = 0;
    
    void signal_handler(int num)
    {
        flag = 1;
    }
    
    int main(void)
    {
        uint64_t bytes = 0;
        sigset_t set;
    
        signal(SIGINT, signal_handler);
        int ret = sigaddset(&set, SIGINT);
    
        while(1) {
            bytes++;
            sigprocmask(SIG_BLOCK, &set, NULL);
            if (flag == 1)
                printf("The number of bytes copied are :%" PRIu64 "\n", bytes);
            flag = 0;
            sigprocmask(SIG_UNBLOCK, &set, NULL);
        }
    }