2015-05-20 2 views
0

Я работаю над встроенным linux с busybox. В рамках моего приложения у меня есть скрипт rc.init E80-startmyprog. Этот скрипт вызывает мою программу prog.Сигнал обработчика SIGHUP сбрасывается по умолчанию при использовании системы() во встроенном Linux с busybox

trap "" HUP 
startmyprog >${LOGFILE} 2>&1 </dev/null & 

startmyprog() { 
    prog 
} 

В моей программе я вижу, что обработчики сигналов настроены на игнорирование SIGHUP. Я проверяю, что с

struct sigaction act; 
sigaction(1, NULL, &act); 
printf("action %p\n", act.sa_sigaction); // prints out 1 -> SIG_IGN 

Теперь на некоторое время в моей программе мне нужно, чтобы начать новый процесс, придать ему некоторый входной сигнал и проверить, если он печатается «да» на стандартный вывод. Я использую систему для этого.

const int ret = system("[ `echo input | second_process` == yes ]"); 

Нормальное поведение является то, что WIFEXITED(ret) верно и что WEXITSTATUS(ret) является 0 или 1.

Но в некоторых случаях с несчастным временем WIFSIGNALED(ret) верно и WTERMSIG(ret) является 1 (SIGHUP).

Отладка показывает, что если Iexecl("second_process", "second_process", (char*)NULL) состояние обработчика сигнала во втором_процессе установлено правильно, SIGHUP = игнорировать. Но если я использую system, то second_process имеет SIGHUP = default.

Мои вопросы:

Что там происходит? Кто перезагружает обработчик сигнала SIGHUP при запуске? Это оболочка? Есть ли способ предотвратить это? (На странице sh man я не видел вариант командной строки, который выглядит так.)

Я знаю, что я мог бы сделать обходной путь и настроить канал, fork, exec second_process, записать вход в трубу, прочитать вывод из трубы и синтаксический анализ, но это много чего по сравнению с системой одного лайнера, и есть хорошие шансы, что я что-то пропущу и ошибаюсь.

+0

Попробуйте 'strace -ff -o/tmp/foo program' - это запустит strace в вашей программе, следуя за вилками и сохраняя результаты трассировки за процесс в /tmp/foo.NNNNN. Я думаю, вы обнаружите, что система (3) НЕ сбрасывает обработчик SIGHUP, хотя, возможно, что-то еще. –

+0

@ Гиль Гамильтон Хорошая точка. Раньше я запускал strace, но только для немного других тестов. Я переделал вашу предложенную strace. Журналы показывают, что порожденные sh вызовы rt_sigaction: 'rt_sigaction (SIGHUP, {0x10000000, [], 0}, {SIG_DFL, [], SA_NOCLDSTOP}, 16) = 0'. –

ответ

0

Копаем глубже в источниках BusyBox, который работает на Linux, я обнаружил, что оболочка в busybox вызывает signal(SIGHUP, SIG_DFL); во время init. Это сбрасывает обработчик sighup по умолчанию. Таким образом, сама оболочка и запущенная ею программа (с -c ...) работают с обработчиком SIGHUP по умолчанию.

Я не вижу пути кода, который обходит сброс обработчика сигнала SIGHUP, поэтому, похоже, я не могу достичь того, чего хочу с помощью system().

1

Я не думаю, что это именно то, что происходит. Когда вы вводите «ловушку» в оболочку, вы просите ее перечислить действия, которые она установила для этого сигнала. Когда вы вызываете подоболочку, вы не делаете никаких действий, поэтому он не будет показывать (он не знает о том, что вы дали своему родителю), но это не означает, что он сбросил состояние SIGHUP.

Попробуйте этот небольшой скрипт, который доказывает SIGHUP до сих пор игнорируется, даже если «ловушку» показывает ничего:

trap "" HUP 
echo "TRAPs in parent" 
trap 
sh -c 'echo "TRAPs in child"; trap; sleep 5; echo "Still here. Traps: "; trap' & 
child=$! 
sleep 1 
kill -HUP $child 
echo 'Killed child' 
+0

ОК, поэтому мое сравнение с тем, что я наблюдаю с bash, не совпадает с тем, что я наблюдаю в своей программе c и 'system'. Я прошу прощения за эту путаницу и удалю часть сравнения bash. –