St.Antario
St.Antario

Reputation: 27455

Not to send SIGINT to a child when SIGINT is sent to a parent

Is there a way to not sent SIGINT to a child process when SIGINT is sent to a parent? Example:

main.c:

#define _GNU_SOURCE
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sched.h>

int run_python(void* arg){
    (void) arg;
    char *const args[] = {"python3", "run.py", NULL };
    execve("/usr/bin/python3", args, NULL);
    return 0;
}

int main(void){
    char *stack = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 1234, 0);
    clone(run_python, stack + 4096,  0, NULL);
    sleep(10);
    return 0;
}

The program that is being run as a child run.py:

import sys
import time
import signal

f = open("output.output", 'w')

def recieved_sigint(*args):
    print("Received sigint", file=f, flush=True)
    sys.exit(1)

signal.signal(signal.SIGINT, recieved_sigint)

while(True):
    print("Test", file=f, flush=True)
    time.sleep(1)

The problem is when executing main.c and pressing Ctrl+C the run.py program also receives SIGINT. The string "Received sigint" is printed.

Is there a way to not send SIGINT to a child that was cloneed-execveed?

Upvotes: 0

Views: 306

Answers (1)

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136525

Note that this is the kernel sending keyboard-generated signals, such as SIGINT, to all processes in the process group attached to the terminal.

Block SIGINT in the parent with sigprocmask before spawning children with clone. The children inherit the signal mask.

After spawning children unblock SIGINT. A pending SIGINT will be delivered upon unblocking, if any.

Ignoring the signal with SIG_IGN while spawning children processes risks discarding the signal which may lead to sporadic missed signal race conditions which don't reproduce reliably.

Upvotes: 4

Related Questions