Chamar kill em um processo filho com SIGTERM encerra o processo pai, mas chamá-lo com SIGKILL mantém o pai vivo
Esta é uma continuação deComo impedir que o SIGINT no processo filho se propague e mate o processo pai?
Na pergunta acima, eu aprendi queSIGINT
não estava sendo borbulhado de filho para pai, mas é emitido para todo o grupo de processos em primeiro plano, o que significa que eu precisava escrever um manipulador de sinal para impedir que o pai saísse quando eu batesseCTRL + C
.
Eu tentei implementar isso, mas aqui está o problema. Em relação especificamente aokill
syscall eu invoco para terminar a criança, se eu passarSIGKILL
, tudo funciona como esperado, mas se eu passarSIGTERM
, ele também finaliza o processo pai, mostrandoTerminated: 15
no prompt do shell mais tarde.
Mesmo que o SIGKILL funcione, eu quero usar o SIGTERM é porque, em geral, parece uma idéia melhor do que eu li sobre ele, dando ao processo que está sinalizando para encerrar a chance de se limpar.
O código abaixo é um exemplo simplificado do que eu vim com
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
pid_t CHILD = 0;
void handle_sigint(int s) {
(void)s;
if (CHILD != 0) {
kill(CHILD, SIGTERM); // <-- SIGKILL works, but SIGTERM kills parent
CHILD = 0;
}
}
int main() {
// Set up signal handling
char str[2];
struct sigaction sa = {
.sa_flags = SA_RESTART,
.sa_handler = handle_sigint
};
sigaction(SIGINT, &sa, NULL);
for (;;) {
printf("1) Open SQLite\n"
"2) Quit\n"
"-> "
);
scanf("%1s", str);
if (str[0] == '1') {
CHILD = fork();
if (CHILD == 0) {
execlp("sqlite3", "sqlite3", NULL);
printf("exec failed\n");
} else {
wait(NULL);
printf("Hi\n");
}
} else if (str[0] == '2') {
break;
} else {
printf("Invalid!\n");
}
}
}
Meu palpite de que isso está acontecendo seria algo que intercepta o SIGTERM e mata todo o grupo de processos. Considerando que, quando eu uso o SIGKILL, ele não pode interceptar o sinal, então minha chamada de morte funciona como esperado. Isso é apenas uma facada no escuro.
Alguém poderia explicar por que isso está acontecendo?
Como observo, não estou emocionado com a minhahandle_sigint
função. Existe uma maneira mais padrão de matar um processo filho interativo?