Linux программирование в примерах

На нашем литературном портале можно бесплатно читать книгу Linux программирование в примерах, Роббинс Арнольд-- . Жанр: Программирование / ОС и Сети. Онлайн библиотека дает возможность прочитать весь текст и даже без регистрации и СМС подтверждения на нашем литературном портале bazaknig.info.
Linux программирование в примерах
Название: Linux программирование в примерах
Дата добавления: 16 январь 2020
Количество просмотров: 975
Читать онлайн

Linux программирование в примерах читать книгу онлайн

Linux программирование в примерах - читать бесплатно онлайн , автор Роббинс Арнольд

В книге рассмотрены вопросы, связанные с программированием под Linux: файловый ввод/вывод, метаданные файлов, основы управления памятью, процессы и сигналы, пользователи и группы, вопросы интернационализации и локализации, сортировка, поиск и многие другие. Много внимания уделено средствам отладки, доступным под GNU Linux. Все темы иллюстрируются примерами кода, взятого из V7 UNIX и GNU. Эта книга может быть полезна любому, кто интересуется программированием под Linux.

 

Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала

Перейти на страницу:

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 childhandlern";

45  static const char exited[] = "Exited childhandlern";

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 statusn");

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

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

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

68   write(1, "tretryingn", 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 --- что сделать в порожденном процессе */

81

82 void child(void)

83 {

84  raise(SIGCONT); /* должен быть проигнорирован */

85  raise(SIGSTOP); /* заснуть, родитель снова разбудит */

86  printf("t---> child restarted <---n");

87  exit(42); /* нормальное завершение, дать возможность родителю получить значение */

88 }

Функция

child()
обрабатывает поведение порожденного процесса, предпринимая действия для уведомления родителя [113]. Строка 84 посылает
SIGCONT
, что может вызвать получение родителем события
CLD_CONTINUED
. Строка 85 посылает
SIGSTOP
, который останавливает процесс (сигнал не может быть перехвачен) и вызывает для родителя событие
CLD_STOPPED
. Когда родитель возобновляет порожденный процесс, последний выводит сообщение, что он снова активен, а затем завершается с известным статусом завершения.

90  /* main --- установка относящихся к порожденному процессу сведений

       и сигналов, создание порожденного процесса */

91

92  int main(int argc, char **argv)

93  {

94   pid_t kid;

95   struct sigaction sa;

96   sigset_t childset, emptyset;

97

98   sigemptyset(&emptyset);

99

100  sa.sa_flags = SA_SIGINFO;

101  sa.sa_sigaction = childhandler;

102  sigfillset(&sa.sa_mask); /* при вызове обработчика все заблокировать */

103  sigaction(SIGCHLD, &sa, NULL);

104

105  sigemptyset(&childset);

106  sigaddset(&childset, SIGCHLD);

107

108  sigprocmask(SIG_SETMASK, &childset, NULL); /* блокировать его в коде main */

109

110  if ((kid = fork()) == 0)

111   child();

112

113  /* здесь выполняется родитель */

114  for (;;) {

115   printf("waiting for signalsn");

116   sigsuspend(&emptyset);

Перейти на страницу:
Комментариев (0)
название