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: signal
void (*signal(int sig, void (*func)(int)))(int)
Onde
func: função callback de tratamento
sig: sinal para tratamento
Retorno
-
Exemplo 4: SIGINT com tratamento
#include <stdio.h>
#include <signal.h>
void ctrl_c(int sig) {
printf("ctrl-c ignorado!\n");
}
int main() {
signal(SIGINT, ctrl_c);
for(;;);
return 0;
}
Entrada
ctrl+c
Saída
^Cctrl-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 ponteiro não iniciado para atribuição indireta de um valor.
Isso irá gerar, implicitamente, 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,
*ponteiro2 = NULL;
ponteiro2 = &var_int;
*ponteiro2 = 0xffffffff;
*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.