Как получить полное возвращаемое значение дочернего процесса?
Мне нужно поймать возвращенное значение дочернего процесса..
Проблема в том, что с помощью функции waitpid() я могу поймать только 8 битов возвращаемого значения
WEXITSTATUS(wstatus) возвращает статус выхода ребенка. Он состоит из наименее значащих 8 битов аргумента состояния, которые дочерний элемент указал в вызове exit(3) или _exit(2) или в качестве аргумента для оператора возврата в main(). Этот макрос должен использоваться, только если WIFEXITED вернул true.
Как я могу поймать полное значение int, которое возвращается из main()
?
РЕДАКТИРОВАТЬ: Stackru заставил меня редактировать вопрос, поскольку он связал другой ответ на вопрос, но это не имеет никакого отношения к моему!
3 ответа
POSIX требует, чтобы полное значение выхода было передано в si_status
член siginfo_t
структура, передаваемая обработчику SIGCHLD, если она установлена надлежащим образом посредством вызова sigaction
с SA_SIGINFO
указано в флагах:
Если si_code равен CLD_EXITED, то si_status содержит значение выхода процесса; в противном случае он равен сигналу, вызвавшему изменение состояния процесса. Выходное значение в si_status должно быть равным полному выходному значению (то есть значению, переданному в _exit(), _Exit() или exit (), или возвращенному из main()); оно не должно быть ограничено младшими восемью битами значения.
(Акцент мой).
Обратите внимание, что после тестирования кажется, что Linux не соблюдает это требование и возвращает только младшие 8 бит кода выхода в элементе si_status. Другие операционные системы могут корректно возвращать полный статус; FreeBSD делает. Смотрите тестовую программу здесь.
Однако, будьте осторожны, не совсем ясно, что вы будете получать отдельный сигнал SIGCHLD для каждого завершения дочернего процесса (несколько ожидающих экземпляров сигнала могут быть объединены), поэтому этот метод не является полностью безошибочным. Вероятно, лучше найти другой способ передачи значения между процессами, если вам нужно более 8 бит.
Короткий ответ: вы почти не можете. Традиционно, состояние выхода процесса в Unix/Linux распространяется как 8-битное значение. Вы можете вернуть любое целое число из main
что вам нравится, вы можете позвонить exit
с любым целым числом, которое вам нравится, но только 8 младших битов доступны для родителя через любой из wait
функции.
Причина WEXITSTATUS
задокументировано, что возвращаются только младшие 8 бит состояния, это то, что это единственные биты, которые есть.
Если вы пытаетесь передать произвольные данные из подпроцесса обратно его родительскому элементу, это не выход из состояния выхода. Я, как правило, я печатаю данные на стандартный вывод, и вызывающий абонент захватывает их, используя popen
или эквивалент
Приложение: Я думал, что ядро даже не записало полный int
статус выхода, и поэтому было невозможно получить его каким-либо образом, но, как объясняет davmac в другом ответе, вы можете получить его в SIGCHLD
обработчик.
Я верю, что вы можете получить это только путем strace
процесс и поиск системных вызовов выхода, которые теперь кажутся exit_group
путем отладки или, возможно, с помощью некоторых уродливых хаков, таких как LD_PRELOAD
, Т.е. ничего ненавязчивого.
Для процессов зомби код выхода можно найти в последнем столбце /proc/<pid>/stat
но это уже & 0xFF
,