Читаем Linux программирование в примерах полностью

«Медленное устройство» является в сущности терминалом или почти всяким другим устройством, кроме обычного файла. В этом случае read() могла завершиться с ошибкой EINTR, лишь если не было передано никаких данных, когда появился сигнал. В противном случае системный вызов был бы запущен повторно, и read() возвратилась бы нормально.

Обычные файлы

Системный вызов был бы запущен повторно В этом случае read() вернулась бы нормально; возвращенное значение могло быть либо числом запрошенных байтов, либо числом действительно прочитанных байтов (как в случае чтения вблизи конца файла).

Поведение BSD несомненно полезно; вы всегда можете сказать, сколько данных было прочитано.

Поведение POSIX сходно, но не идентично первоначальному поведению BSD. POSIX указывает, что read()[108] завершается с ошибкой EINTR лишь в случае появления сигнала до начала перемещения данных. Хотя POSIX ничего не говорит о «медленных устройствах», на практике это условие проявляется именно на них.

В противном случае, если сигнал прерывает частично выполненную read(), возвращенное значение является числом уже прочитанных байтов. По этой причине (а также для возможности обработки коротких файлов) всегда следует проверять возвращаемое read() значение и никогда не предполагать, что прочитано все запрошенное количество байтов. (Функция POSIX API sigaction(), описанная позже, позволяет при желании получить поведение повторно вызываемых системных вызовов BSD.)

<p>10.4.4.1. Пример: GNU Coreutils <code>safe_read()</code> и <code>safe_write()</code></p>

Для обработки случая EINTR в традиционных системах GNU Coreutils использует две функции, safe_read() и safe_write(). Код несколько запутан из-за того, что один и тот же файл за счет включения #include и макросов реализует обе функции. Из файла lib/safe-read.c в дистрибутиве Coreutils:

1  /* Интерфейс read и write для .повторных запусков после прерываний.

2     Copyright (С) 1993, 1994, 1998, 2002 Free Software Foundation, Inc.

   /* ... куча шаблонного материала опущена... */

56

57 #ifdef SAFE_WRITE

58 # include "safe-write.h"

59 # define safe_rw safe_write /* Создание safe_write() */

60 # define rw write /* Использование системного вызова write() */

61 #else

62 # include "safe-read.h"

63 # define safe_rw safe_read /* Создание safe_read() */

64 # define rw read /* Использование системного вызова read() */

65 # undef const

66 # define const /* пусто */

67 #endif

68

69 /* Прочесть (записать) вплоть до COUNT байтов в BUF из(в) дескриптора FD, повторно запуская вызов при

70 прерывании. Вернуть число действительно прочитанных (записанных) байтов, 0 для EOF

71 или в случае ошибки SAFE_READ_ERROR(SAFE_WRITE_ERROR). */

72 size_t

73 safe_rw(int fd, void const *buf, size_t count)

74 {

75  ssize_t result;

76

77  /* POSIX ограничивает COUNT значением SSIZE_MAX, но мы еще больше ограничиваем его, требуя,

78  чтобы COUNT <= INT_MAX, для избежания ошибки в Tru64 5.1.

79  При уменьшении COUNT сохраняйте указатель файла выровненным по размеру блока.

80  Обратите внимание, что read (write) может быть успешным в любом случае, даже если прочитано (записано)

81  менее COUNT байтов, поэтому вызывающий должен быть готов обработать

82  частичные результаты. */

83  if (count > INT_MAX)

84   count = INT_MAX & -8191;

85

86  do

87  {

88   result = rw(fd, buf, count);

89  }

90  while (result < 0 && IS_EINTR(errno));

91

92  return (size_t) result;

93 }

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

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных