Antonio
Antonio

Reputation: 27

Why does SIGINT stop sleep more than one time?

I don't understand why after the first execution of kill function the sleep function doesn't pause the parent process. After the SIGINT has been delivered, many processes are generated. Furthermore, it seems that a variable number of processes is generated. Is a handler for SIGINT required for cleaning the first SIGINT from the pending signals?

void handler(int s) {
    int status;
    wait(&status);
    printf("\n in the handler");
    if (WIFSIGNALED(status)) {
        int sig=WTERMSIG(status);
        printf("\n child stopped by signal %d\n",sig);
    }
    if (WIFEXITED(status)) {
        int ex=WEXITSTATUS(status);
        printf("\n child stopped with exist status %d\n",ex);
    }
}

int main() {
    int pid,len, count, ret;
    char s[1024];
    signal(SIGCHLD,handler);
    while(1) {
        pid=fork();
        if (pid==0) {
            printf("\n Write something ");
            scanf("%s",s);
            len=strlen(s);
            printf("\n Characters: %d",len);
            return 1;
        }
        else {
            sleep(20);
            kill(pid,SIGINT);
        }
    }
}

Upvotes: 1

Views: 548

Answers (1)

Petr Skocik
Petr Skocik

Reputation: 60067

The SIGCHLD from the previous child-death-causing kill is arriving just when you're in the next sleep.

Sleep is an interruptible function. If a signal handler runs while your thread is in it, the sleep is going to abort. So then you proceed to the next kill, which is going to indirectly cause another SIGCHLD which will most likely happen when your next iteration's sleep, resulting in several skipped sleeps.

If you insert sleep(1) before fork(), it should (practically) shift the timing just right so that next sleep(20); is uninterrupted.

(I'm treating this as a quick-and-dirty experiment. In no way is it a good idea to rely on "adjustments" like this in production code (or to use printf in signal handlers for that matter).)

Upvotes: 2

Related Questions