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

10.4.4.2. Только GLIBC: TEMP_FAILURE_RETRY()

10.4.4.2. Только GLIBC: TEMP_FAILURE_RETRY()

Файл <unistd.h> GLIBC определяет макрос TEMP_FAILURE_RETRY(), который вы можете использовать для инкапсулирования любого системного вызова, который может при неудачном вызове установить errno в EINTR. Его «объявление» следующее:

#include <unistd.h> /* GLIBC */
long int TEMP_FAILURE_RETRY(expression);

Вот определение макроса:

/* Оценить EXPRESSION и повторять, пока оно возвращает -1 с 'errno',
    установленным в EINTR. */
# define TEMP_FAILURE_RETRY(expression)
 (__extension__
  ({ long int __result;
   do __result = (long int)(expression);
   while (__result == -1L && errno == EINTR);
   __result; }))

Макрос использует расширение GCC к языку С (как обозначено ключевым словом __extension__), которое допускает заключенным в фигурные скобки внутри обычных скобок выражениям возвращать значение, действуя таким образом подобно простому выражению.

Используя этот макрос, мы могли бы переписать safe_read() следующим образом:

size_t safe_read(int fd, void const *buf, size_t count) {
 ssize_t result;
 /* Ограничить count, как в ранее приведенном комментарии. */
 if (count > INT_MAX)
  count = INT_MAX & ~8191;
 result = TEMP_FAILURE_RETRY(read(fd, buf, count));
 return (size_t)result;
}

Оглавление книги

Похожие страницы

Генерация: 1.226. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз