1

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);
        }
    }
}
Barmar
  • 741,623
  • 53
  • 500
  • 612
Antonio
  • 29
  • 5
  • 2
    Try running with `strace` to see what's happening. – Barmar May 08 '19 at 16:30
  • 1
    Two potential issues. First, you can't safely call `printf()` in a signal handler as it's not async-signal-safe. See https://stackoverflow.com/questions/34467694/why-only-async-signal-safe-functions-can-be-called-from-signal-handlers-safely for one example question. Second, you might want to [use `sigaction()` instead of `signal()`](https://stackoverflow.com/questions/231912/what-is-the-difference-between-sigaction-and-signal). – Andrew Henle May 08 '19 at 16:58

1 Answers1

2

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).)

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142