Eu fiz mais algumas investigações, e descobri que ...killed
é realmente impresso pelo programa su
, embora a impressão não venha do projeto coreutils upstream, ele é introduzido pelo coreutils-8.5-pam.patch no fonte rpm. Há alguma história sobre as origens para adicionar isso no bugzilla ( 622700 , 597928 e 240117 ).
A parte relevante do código é
static sig_atomic_t volatile caught_signal = false;
...
/* Signal handler for parent process. */
static void
su_catch_sig (int sig)
{
caught_signal = true;
}
...
static void
create_watching_parent (void)
{
...
sigfillset (&ourset);
if (sigprocmask (SIG_BLOCK, &ourset, NULL))
{
error (0, errno, _("cannot block signals"));
caught_signal = true;
}
if (!caught_signal)
{
...
action.sa_handler = su_catch_sig;
...
|| sigaction (SIGTERM, &action, NULL)
...
if (caught_signal)
{
fprintf (stderr, _("\nSession terminated, killing shell..."));
kill (child, SIGTERM);
}
cleanup_pam (PAM_SUCCESS);
if (caught_signal)
{
sleep (2);
kill (child, SIGKILL);
fprintf (stderr, _(" ...killed.\n"));
}
exit (status);
}
Portanto, de alguma forma (direta ou indiretamente relacionada a cleanup_pam ou não relacionada) o processo pai recebe SIGTERM entre o segundo último e o último se testes e, portanto, imprime apenas a mensagem ...killed
que obviamente deveria ter sido uma continuação de o fprintf acima.
Apesar de tudo, o uso duplo de caught_signal
como um manipulador de sinal assíncrono significa e como uma variável de controle de fluxo local dentro da função parece um hack realmente sujo e eu não gostei do código. Eu testei dividindo isso e introduzi uma variável booleana kill_child para usar no corpo da função e depois ter
if (caught_signal)
{
kill_child:
kill_child = true;
status = 1;
}
if (kill_child) {
{
fprintf (stderr, _("\nSession terminated, killing shell..."));
kill (child, SIGTERM);
}
cleanup_pam (PAM_SUCCESS);
if (kill_child)
{
sleep (2);
kill (child, SIGKILL);
fprintf (stderr, _(" ...killed.\n"));
}
exit (status);
}
no final da função. Com essa modificação eu não recebo mais ....killed
spam de anacron.
Portanto, uma longa explicação e possivelmente mais informações do que você precisa. Contudo. Eu também descobri um pouco mais, o que é uma boa notícia para você, já que você não precisa fazer modificações locais no pacote coreutils. Para casos como executar o su do cron, você deve rodar o programa runuser instead . É uma espécie de notícia "ruim" para mim, pois torna minhas descobertas acima menos importantes, mas bem bem:).