Я провел дальнейшее расследование и обнаружил, что ...killed
действительно печатается программой su
, хотя печать не идет из проекта coreutils из основной ветки разработки, она вводится coreutils-8.5-pam.patch в исходную версию rpm. Существует некоторая история о происхождении добавления этого в bugzilla (622700 , 597928 и 240117).
Соответствующая часть кода
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);
}
Таким образом, в некотором роде (прямо или косвенно связанный с cleanup_pam или не связанным) родительский процесс получает SIGTERM между вторым последним и последним тестами if и, таким образом, печатает только сообщение ...killed
которое, очевидно, должно было быть продолжением fprintf. выше.
В общем, двойное использование caught_signal
как средства обработки асинхронного сигнала и как локальной переменной управления потоком внутри функции выглядит как очень грязный хак, и мне не понравился код. Я проверил это, разделив его, и ввел логическую переменную kill_child для использования в теле функции, а затем
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);
}
в конце функции. С этой модификацией я больше не получаю ....killed
спам от анакрона.
Так что длинное объяснение и, возможно, больше информации, чем вам нужно. Тем не мение. Я также узнал еще кое-что, что является хорошей новостью для вас, поскольку вам не нужно вносить локальные изменения в пакет coreutils. В таких случаях, как запуск su из cron, вы должны вместо этого запустить программу runuser. Это своего рода "плохие" новости для меня, так как это делает мои выводы менее важными, но хорошо :).