Вход/Регистрация
Linux программирование в примерах
вернуться

Роббинс Арнольд

Шрифт:

1 /* ch10-status.c --- демонстрирует управление SIGCHLD, используя обработчик с 3 аргументами */

2

3 #include <stdio.h>

4 #include <errno.h>

5 #include <signal.h>

6 #include <string.h>

7 #include <sys/types.h>

8 #include <sys/wait.h>

9

10 void manage(siginfo_t *si);

11

/* ...не изменившийся для format_num код опущен... */

Таблица 10.5. Значения

si_code
XSI для
SIGCHLD

Значение Смысл
CLD_CONTINUED
Остановленный потомок был возобновлен.
CLD_DUMPED
Потомок завершился с ошибкой, создан образ процесса
CLD_EXITED
Потомок завершился нормально.
CLD_KILLED
Потомок был завершен сигналом
CLD_STOPPED
Порожденный процесс был остановлен.
CLD_TRAPPED
Трассируемый потомок остановлен (Это условие возникает, когда программа трассируется — либо из отладчика, либо для мониторинга реального времени В любом случае, вы вряд ли увидите его в обычных ситуациях.)

Строки 3–8 включают стандартные заголовочные файлы, строка 10 объявляет

manage
, которая имеет дело с изменениями состояния потомка, а функция
format_num
не изменилась по сравнению с предыдущим.

37 /* childhandler --- перехват SIGCHLD, сбор данных лишь об одном потомке */

38

39 void childhandler(int sig, siginfo_t *si, void *context)

40 {

41 int status, ret;

42 int i;

43 char buf[100];

44 static const char entered[] = "Entered childhandler\n";

45 static const char exited[] = "Exited childhandler\n";

46

47 write(1, entered, strlen(entered));

48 retry:

49 if ((ret = waitpid(si->si_pid, &status, WNOHANG)) == si->si_pid) {

50 strcpy(buf, "\treaped process ");

51 strcat(buf, format_num(si->si_pid));

52 strcat(buf, "\n");

53 write(1, buf, strlen(buf));

54 manage(si); /* обработать то, что произошло */

55 } else if (ret > 0) {

56 strcpy(buf, "\treaped unexpected pid ");

57 strcat(buf, format_num(ret));

58 strcat(buf, "\n");

59 write(1, buf, strlen(buf));

60 goto retry; /* почему бы нет? */

61 } else if (ret == 0) {

62 strcpy(buf, "\tpid ");

63 strcat(buf, format_num(si->si_pid));

64 strcat(buf, " changed status\n");

65 write(1, buf, strlen(buf));

66 manage(si); /* обработать то, что произошло */

67 } else if (ret == -1 && errno == EINTR) {

68 write(1, "\tretrying\n", 10);

69 goto retry;

70 } else {

71 strcpy(buf, "\twaitpid failed: ");

72 strcat(buf, strerror(errno));

73 strcat(buf, "\n");

74 write(1, buf, strlen(buf));

75 }

76

77 write(1, exited, strlen(exited));

78 }

Обработчик сигнала похож на показанные ранее. Обратите внимание на список аргументов (строка 39) и на то, что нет цикла.

Строки 49–54 обрабатывают завершение процесса, включая вызов

manage
для вывода состояния.

Строки 55–60 обрабатывают случай неожиданного завершения потомка. Этого не должно происходить, поскольку обработчику сигнала передается специфическая для определенного порожденного процесса информация.

Строки 61–66 представляют для нас интерес: возвращаемое значение для изменений состояния равно 0.

manage
имеет дело с деталями (строка 66).

Строки 67–69 обрабатывают прерывания, а строки 70–75 распоряжаются ошибками

80 /* child --- что сделать в порожденном процессе */

  • Читать дальше
  • 1
  • ...
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: