De acordo com a situação em que nosso programa se encontra: erro, validação ou outro,
o tratamento do sinal pode ser utilizado para liberar recursos alocados.
Sintaxe:
void (*signal(int sig, void (*func)(int)))(int)
Onde
*func: função callback
sig: sinal para tratamento
Retorno
-
Exemplo 4: SIGINT com tratamento
#include <stdio.h>
#include <signal.h>
void ctrl_c(int sig) {
printf("\nctrl-c ignorado!\n");
}
int main() {
signal(SIGINT, ctrl_c);
for(;;); //loop infinito
return 0;
}
Entrada
ctrl+c
Saída
^C
ctrl-c ignorado!
Exemplo 5: SIGTERM
#include <stdio.h>
#include <signal.h>
void tratamento(int sig) {
printf("parâmetro invalido");
exit(1) //atexit se registrada
}
int main()
{
signal(SIGTERM, tratamento);
//signal(SIGABRT,tratamento);
int a = 0;
if(a == 0){
raise(SIGTERM);
//raise(SIGABRT);
}
return 0;
}
Saída
parâmetro invalido
No próximo exemplo, vamos utilizar um ponteiron, não iniciado, e tentar atribuir um
endereço de memória indiretamente. Isso irá gerar um sinal SIGSEGV que será
capturado em uma função de tratamento configurada pela função signal.
Exemplo 6: Violação de memória
#include <stdio.h>
#include <signal.h>
void tratamento(int sig) {
printf("SIGSEGV! detectado!\n");
//tratamento
raise(SIGABRT);
}
int main()
{
int var_int = 0;
signal(SIGSEGV, tratamento); //registra SIGSEGV
int *ponteiro1 = NULL;
*ponteiro1 = 0xffffffff; //violação de acesso SIGSEGV
return 0;
}
Saída
SIGSEGV detectado!
Os sinais e seus tratamentos podem ser utilizados em conjunto com as funções exit ou atexit
para uma melhor organização de tratamento de erros ao encerrar um programa utilizando SIGTERM
e SIGABRT, por exemplo.