Как получить полное возвращаемое значение дочернего процесса?

Мне нужно поймать возвращенное значение дочернего процесса..

Проблема в том, что с помощью функции 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,

Другие вопросы по тегам