Я должен записать программу C, чтобы проверить, как init реагирует на различные сигналы уничтожения, однако я не уверен, как зарегистрировать его - например, сигнал номер 14 разрушает человечность, затем некоторые выше, что каждый выключает его. Там какой-либо путь состоит в том, чтобы зарегистрировать его правильно так, чтобы я знал, как система реагирует на каждый сигнал? Вот код C, который я использую, любая обратная связь на этом также ценилась бы:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int sigs[64] = { 0 };
for(int i = 0; i < 64; i++) sigs[i] = i+1;
char sigs_char[64][2];
for(int i = 0; i < 64; i++) sprintf(sigs_char[i], "%d", sigs[i]);
char one[2] = " 1";
char commands[64][128];
for(int i = 0; i < 64; i++){
strcpy(commands[i], "sudo kill -s ");
strncat(commands[i], sigs_char[i], 2);
strcat(commands[i], one);
}
for(int i = 0; i < 64; i++){
printf("Sending signal number %d\n", i);
system(commands[i]);
}
return 0;
}
Я боюсь, что нет никакого общего способа "зарегистрироваться" init
реакция. Во-первых, существует факт это kill
не поставит сигналов init
это init
не обрабатывает (от man 2 kill
):
NOTES
The only signals that can be sent to process ID 1, the init process,
are those for which init has explicitly installed signal handlers.
This is done to assure the system is not brought down accidentally.
Так, для многих сигналов не будет реакции вообще. Теперь, когда оставляют сигналы, которые обрабатываются. Используя этот вопрос о Unix & Linux, мы можем определить those1:
$ HANDLED_SIGS=$(awk '/SigCgt/{print "0x"$2}' /proc/1/status)
$ for i in {0..31}; do (( (1 << i) & $HANDLED_SIGS )) && echo $((++i)) $(/bin/kill --list=$i); done | column
1 HUP 6 ABRT 11 SEGV 15 TERM 30 PWR
2 INT 10 USR1 14 ALRM 17 CHLD 32
Из них:
SIGABRT
и SIGSEGV
вызванные дампы ядра и паника ядра. Ничто, чтобы быть обнаруженным здесь.SIGTERM
вызванный это для перезагрузки, с журналом обменивается сообщениями в /var/log/syslog
:
Nov 14 00:25:13 vm kernel: [32383.384907] init: upstart-udev-bridge main process (395) terminated with status 1
Nov 14 00:25:13 vm kernel: [32383.384916] init: upstart-udev-bridge main process ended, respawning
Nov 14 00:25:13 vm kernel: [32383.384990] init: upstart-socket-bridge main process (649) terminated with status 1
Nov 14 00:25:13 vm kernel: [32383.384995] init: upstart-socket-bridge main process ended, respawning
Nov 14 00:25:13 vm kernel: [32383.385059] init: upstart-file-bridge main process (953) terminated with status 1
Nov 14 00:25:13 vm kernel: [32383.385074] init: upstart-file-bridge main process ended, respawning
SIGINT
вызванный это для запуска перезагрузки, и SIGPWR
запущенный завершение работы. Оба были похожи на нормальные (скажите, как то, если Вы сделали a reboot
, например).init
обязанности, мы можем предположить что SIGCHLD
делает.)И все это для Выскочки. Кто знает, как SysV или systemd будут реагировать?
Так, в целом, Вы не собираетесь иметь много удачи с эмпирическими методами здесь. Используйте Источник, Luke.
1That замысловатый бит кода - для получения сигналов это init
готово поймать:
HANDLED_SIGS=$(awk '/SigCgt/{print "0x"$2}' /proc/1/status)
for i in {0..31}
do
(( (1 << i) & $HANDLED_SIGS )) && echo $((++i)) $(/bin/kill --list=$i);
done | column
HANDLED_SIGS=$(awk '/SigCgt/{print "0x"$2}' /proc/1/status)
: /proc/$PID/status
содержит богатство информации о процессе, включая набор обработанных сигналов. Этим набором дают SigCgt
, битовая маска дана как шестнадцатеричное число. Мы используем awk
извлечь то число и добавить 0x
как префикс.(( (1 << i) & $HANDLED_SIGS ))
: проверьте если сигнал нет. (i+1)
маскируется. Так как мы обеспокоены i
th укусил, мы используем 2 (i-1) (который является 1 << i
). С (( ))
, ненулевое значение указывает на успех.