57 if ((ret = waitpid(kids[i], &status, WNOHANG)) == kids[i]) {
58 strcpy(buf, "\treaped process ");
59 strcat(buf, format_num(ret));
60 strcat(buf, "\n");
61 write(1, buf, strlen(buf));
62 kids[i] = NOT_USED;
63 } else if (ret == 0) {
64 strcpy(buf, "\tpid ");
65 strcat(buf, format_num(kids[i]));
66 strcat(buf, " not available yet\n");
67 write(1, buf, strlen(buf));
68 } else if (ret == -1 && errno == EINTR) {
69 write(1, "\tretrying\n", 10);
70 goto retry;
71 } else {
72 strcpy(buf, "\twaitpid failed: ");
73 strcat(buf, strerror(errno));
74 strcat(buf, "\n");
75 write(1, buf, strlen(buf));
76 }
77 }
78 write(1, exited, strlen(exited));
79 }
Строки 51 и 58 выводят «входное» и «завершающее» сообщения, так что мы можем ясно видеть, когда вызывается обработчик сигнала. Другие сообщения начинаются с ведущего символа TAB.
Главной частью обработчика сигнала является большой цикл, строки 52–77. Строки 53–54 проверяют на
NOT_USED
и продолжают цикл, если текущий слот не используется.
Строка 57 вызывает
waitpid
с PID текущего элемента
kids
. Мы предусмотрели опцию
WNOHANG
, которая заставляет
waitpid
возвращаться немедленно, если затребованный потомок недоступен. Этот вызов необходим, так как возможно, что не все потомки завершились.
Основываясь на возвращенном значении, код предпринимает соответствующее действие. Строки 57–62 обрабатывают случай обнаружения потомка, выводя сообщение и помещая в соответствующий слот в