El proceso secundario recibe el SIGINT de los padres

Tengo un progtwig simple que usa Qt Framework. Utiliza QProcess para ejecutar RAR y comprimir algunos archivos. En mi progtwig estoy capturando SIGINT y haciendo algo en mi código cuando ocupa:

signal(SIGINT, &unix_handler); 

Cuando aparece SIGINT, compruebo si el proceso RAR está hecho, y si no lo está, lo esperaré … El problema es que (creo) el proceso RAR también obtiene el SIGINT que fue diseñado para mi progtwig y se cierra antes ha comprimido todos los archivos.

¿Hay alguna forma de ejecutar el proceso RAR para que no reciba SIGINT cuando mi progtwig lo recibe?

Gracias

Si está generando el SIGINT con Ctrl-c en un sistema Unix, entonces la señal se envía a todo el grupo de procesos .

Debe usar setpgid o setsid para colocar el proceso secundario en un grupo de procesos diferente para que no reciba las señales generadas por el terminal de control.

[editar]

Asegúrese de leer la sección JUSTIFICACIÓN de la página setpgid cuidado. Es un poco complicado conectar todas las posibles condiciones de carrera aquí.

Para garantizar al 100% que no se entregará SIGINT al proceso de su hijo, debe hacer algo como esto:

 #define CHECK(x) if(!(x)) { perror(#x " failed"); abort(); /* or whatever */ } /* Block SIGINT. */ sigset_t mask, omask; sigemptyset(&mask); sigaddset(&mask, SIGINT); CHECK(sigprocmask(SIG_BLOCK, &mask, &omask) == 0); /* Spawn child. */ pid_t child_pid = fork(); CHECK(child_pid >= 0); if (child_pid == 0) { /* Child */ CHECK(setpgid(0, 0) == 0); execl(...); abort(); } /* Parent */ if (setpgid(child_pid, child_pid) < 0 && errno != EACCES) abort(); /* or whatever */ /* Unblock SIGINT */ CHECK(sigprocmask(SIG_SETMASK, &omask, NULL) == 0); 

Estrictamente hablando, cada uno de estos pasos es necesario. Tienes que bloquear la señal en caso de que el usuario toque Ctrl-C justo después de la llamada al fork . Tienes que llamar a setpgid en el niño en caso de que el execl ocurra antes de que el padre tenga tiempo para hacer algo. Tienes que llamar a setpgid en el padre en caso de que el padre se ejecute y alguien toque Ctrl-C antes de que el niño tenga tiempo de hacer algo.

La secuencia anterior es torpe, pero maneja el 100% de las condiciones de carrera.

¿Qué estás haciendo en tu controlador? Solo hay ciertas funciones de Qt a las que puede llamar de forma segura desde un manejador de señal de Unix. Esta página en la documentación identifica cuáles son.

El problema principal es que el controlador se ejecutará fuera del hilo principal del evento Qt. Esa página también propone un método para tratar con esto. Prefiero que el controlador “publique” un evento personalizado en la aplicación y lo maneje de esa manera. Publiqué una respuesta que describe cómo implementar eventos personalizados aquí .