Cuando presionas Ctr + C , el sistema operativo envía una señal al proceso. Hay muchas señales y una de ellas es SIGINT. SIGINT ("interrupción de programa") es una de las señales de terminación.
Hay algunos tipos más de señales de terminación, pero lo interesante de SIGINT es que puede ser manejado (atrapado) por su programa. La acción predeterminada de SIGINT es la finalización del programa. Es decir, si su programa no maneja específicamente esta señal, cuando presione Ctr + C su programa termina como la acción predeterminada.
Para cambiar la acción predeterminada de una señal, debe registrar la señal que desea capturar. Para registrar una señal en un programa C (al menos bajo sistemas POSIX) hay dos funciones
- señal(int signum, manejador sighandler_t);
- sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);.
Estas funciones requieren que el encabezado signal.h se incluya en su código C. He proporcionado un ejemplo simple del signal
función a continuación con comentarios.
#include <stdio.h>
#include <stdlib.h>
#include <signal.h> // our new library
volatile sig_atomic_t flag = 0;
void my_function(int sig){ // can be called asynchronously
flag = 1; // set flag
}
int main(){
// Register signals
signal(SIGINT, my_function);
// ^ ^
// Which-Signal |-- which user defined function registered
while(1)
if(flag){ // my action when signal set it 1
printf("\n Signal caught!\n");
printf("\n default action it not termination!\n");
flag = 0;
}
return 0;
}
Nota:solo debe llamar a funciones seguras/autorizadas en el controlador de señales. Por ejemplo, evite llamar a printf en el controlador de señales.
Puede compilar este código con gcc y ejecutarlo desde el shell. Hay un bucle infinito en el código y se ejecutará hasta que envíes un SIGINT
señal presionando Ctr + C .
Puedes usar la macro de señal.
Aquí hay un ejemplo de cómo lidiar con eso:
#include <signal.h>
#include <stdio.h>
void sigint(int a)
{
printf("^C caught\n");
}
int main()
{
signal(SIGINT, sigint);
for (;;) {}
}
Salida de muestra:
Ethans-MacBook-Pro:~ phyrrus9$ ./a.out
^C^C caught
^C^C caught
^C^C caught
^C^C caught
^C^C caught
Escribiendo Ctrl C normalmente hace que el shell envíe SIGINT
a su programa. Agregue un controlador para esa señal (a través de signal(2)
o sigaction(2)
), y puedes hacer lo que quieras cuando Ctrl C está presionado.
Alternativamente, si solo le importa hacer la limpieza antes de que su programa salga, configure un controlador de salida a través de atexit(3)
podría ser más apropiado.