Search code examples
clinuxsignal-handling

Another signal with sigtimedwait


This code is handle SIGINT signal during 100 seconds or print timeout if SIGINT didn't arrive.

#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
 

int main (int argc, char *argv[])
{
    sigset_t mask;
    sigset_t orig_mask;
    struct timespec timeout;

 
    sigemptyset (&mask);
    sigaddset (&mask, SIGINT);
 
    if (sigprocmask(SIG_BLOCK, &mask, &orig_mask) < 0) {
        perror ("sigprocmask");
        return 1;
    }
 
    timeout.tv_sec = 100;
    timeout.tv_nsec = 0;
 
    
    int v =sigtimedwait(&mask, NULL, &timeout);
    if (errno == EAGAIN) {
        printf ("Timeout\n");
        return -1;
       }
    if(v== SIGINT){
        printf("SIGINT\n");
        return 1;
        }

 
    return 0;
}

When code is in sigtimedwait if another signal than SIGINT will arrive, is the code will continue ? Or sigtimedwait will finish only when SIGINT will arrive?

In addition if before this code I will register to another signal like signal(SIGUSR1, handle_sig); , when the code in sigtimedwait and SIGUSR1 will arrived ,is handle_sig will called?or it will blocked ?

int main (int argc, char *argv[])
{

    signal(SIGUSR1, handle_sig);// 
    sigset_t mask;
    sigset_t orig_mask;
    struct timespec timeout;

 
    sigemptyset (&mask);
    sigaddset (&mask, SIGINT);
 
    if (sigprocmask(SIG_BLOCK, &mask, &orig_mask) < 0) {
        perror ("sigprocmask");
        return 1;
    }
 
    timeout.tv_sec = 100;
    timeout.tv_nsec = 0;
 
    
    int v =sigtimedwait(&mask, NULL, &timeout);
    if (errno == EAGAIN) {
        printf ("Timeout\n");
        return -1;
       }
    if(v== SIGINT){
        printf("SIGINT\n");
        return 1;
        }

 
    return 0;
}

Solution

  • (code 1) When code is in sigtimedwait if another signal than SIGINT will arrive, is the code will continue ?

    If SIGKILL, SIGTERM, SIGUSR1, SIGUSR2 .... any other signal with default action to terminate the process will arrive, the process will be terminated. If signal SIGCHLD or SIGURG arrives, they will be ignored - the code will "continue" to be in sigtimedwait (because there is no handler to be executed for these signals). If a stop signal (SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU) the process will be stopped. When after SIGSTOP we resume the process (by sending SIGCONT), then sigtimedwait will return -1 and errno will be set to EINTR. For more information, see man 7 signal and posix sigtimedwait and posix signal concepts.

    (code 2) when the code in sigtimedwait and SIGUSR1 will arrived, will handle_sig be called?

    Yes.

    or it will blocked ?

    No. The signal handler will be executed, then sigtimedwait will return -1 and errno will be set to EINTR.

    (TBH why didn't you just test the code? Looks trivial to put some write(1 in signal handler, compiler and run the process and send a SIGUSR1 signal to it and see what happens)

    maybe it's depending on architecture

    It's not - the behavior depends not on architecture, but on the behavior of an operating system - on the underlying software that is responsible for forwarding and handling of signals to processes and managing them. An POSIX compliant operating system has to do what is specified by POSIX, independent on architecture it's running on.