Главная » Haskell » Модуль C

0

Модуль, который включает в себя при помощи реимпорта функциональность трёх нижеследующих модулей, описывающих  специфические функции для работы в рамках подхода FFI (Foreign Function Interface — интерфейс  к внешним функциям) с внешними  программами, написанными на языке  программирования C. Использование:

import Foreign.C

10.1.1.    Модуль Error

Модуль Error описывает набор программных сущностей, позволяющих обрабатывать коды ошибок в стиле языка C (понятие «errno»  из этого языка программирования). Использование:

import  Foreign.C.Error

Коды ошибок представляют  собой целые числа. В языке Haskell для их представления используется изоморфный тип Errno.

Тип: Errno

Описание: представление кодов ошибок из языка C в языке программирования Haskell. Это представление  преднамеренно  сделано  открытым  (не определено в виде примитива), чтобы разрешить пользователям определять и обрабатывать свои коды ошибок.

Определение:

newtype Errno  =  Errno  CInt

Для данного типа определён экземпляр класса Eq.

Различные операционные системы и (или) различные библиотеки  языка C определяют константы  для представления  кодов  ошибок  по-разному. Поэтому такими константами необходимо пользоваться с известной долей осторожности.  В этом модуле определены константные функции для наиболее общих кодов ошибок. Но в силу открытости определения типа Errno, разработчик может добавлять свои определения, которые отсутствуют в этом модуле.

В рассматриваемом модуле определено около ста константных функций, возвращающих определённое значение  типа Errno.  Все эти  функции имеют шаблонные наименования.  Они начинаются со  строчной буквы  e, после которой идёт обозначение кода ошибки полностью заглавными буквами. Например: eOK, ePROTONOSUPPORT  или  eXDEV.  Нет никакого  смысла в перечислении  всех этих функций здесь, поскольку их можно просмотреть в исходном коде модуля.

Далее описываются функции, которые помогают обрабатывать коды ошибок.

Функция: isValidErrno

Описание: возвращает значение True, если переданный на вход код ошибки является валидным в системе исполнения программы.  Отсюда следует, что экземпляр

класса Eq для типа Errno также является зависимым от системы и работает только с валидными кодами ошибок.

Определение:

isValidErrno :: Errno  ->  Bool isValidErrno (Errno  errno) = errno   /=  -1

Функция: getErrno

Описание: возвращает текущее значение кода errno  для текущего потока управления.

Определение:

getErrno :: IO Errno

getErrno = do e < get_errno return  (Errno  e)

Функция: resetErrno

Описание: сбрасывает текущий код ошибки в значение eOK.

Определение:

resetErrno  ::  IO () resetErrno =  set_errno 0

Функция: errnoToIOError

Описание: создаёт на основе кода ошибки представление этой ошибки в системе обработки ошибок языка Haskell. Третий и четвёртый аргументы функции могут быть использованы для увеличения точности преобразования. Первый аргумент представляет описание места, где произошла ошибка. Второй — собственно  код ошибки. Третий (опционально) — обработчик файла, ассоциированный с ошибкой. Четвёртый (опционально)  — имя файла, ассоциированное с ошибкой. Определение:

errnoToIOError :: String ->  Errno  ->  Maybe Handle ->  Maybe  String  ->  IOError errnoToIOError loc   errno   maybeHdl maybeName

=  unsafePerformIO  $

do str < strerror errno   >>= peekCString

return (userError (loc ++ ": " ++ str ++ maybe "" (": "++)  maybeName))

Функция: throwErrno

Описание: выбрасывает исключение типа IOError на основе текущего кода ошибки. Первый аргумент используется как текстовое описание ошибки. Определение:

throwErrno :: String ->  IO a throwErrno loc   = do errno   < getErrno

ioError  (errnoToIOError loc   errno   Nothing  Nothing)

Функция: throwErrnoIf

Описание: выбрасывает исключение, соответствующее текущему значению кода ошибки, если результат заданного действия в монаде IO удовлетворяет заданному предикату. Первый аргумент является предикатом. Второй — текстовым описанием ошибки. Третий — монадическое  действие ввода/вывода, которое необходимо выполнить.

Определение:

throwErrnoIf :: (a  ->  Bool)   ->  String ->  IO a  ->  IO a throwErrnoIf pred  loc   f = do res  < f

if  pred  res

then  throwErrno  loc  else  return res

Функция: throwErrnoIf-

Описание: вариант функции throwErrnoIf, который  игнорирует  результат выполненного действия (используется тогда, когда результат не важен, но важны побочные эффекты монады IO).

Определение:

throwErrnoIf_ :: (a  ->  Bool)   ->  String ->  IO a ->  IO () throwErrnoIf_ pred  loc   f = void  $  throwErrnoIf pred  loc   f

Функция: throwErrnoIfRetry

Описание: вариант функции throwErrnoIf, который повторяет заданное монадическое действие, если текущий код ошибки равен значению eINTR. Это значение является стандартным  для циклов повторения в системах стандарта POSIX.

Определение:

throwErrnoIfRetry :: (a  ->  Bool)   ->  String ->  IO a ->  IO a throwErrnoIfRetry pred  loc   f = do  res  < f

if  pred  res

then  do err  < getErrno if  err  ==  eINTR

then  throwErrnoIfRetry  pred  loc   f else  throwErrno loc

else  return  res

Функция: throwErrnoIfRetry-

Описание: вариант функции throwErrnoIfRetry, который игнорирует результат выполненного действия (используется тогда, когда результат не важен, но важны побочные эффекты монады IO).

Определение:

throwErrnoIfRetry_ :: (a  ->  Bool)   ->  String ->  IO a ->  IO  () throwErrnoIfRetry_ pred  loc   f = void  $  throwErrnoIfRetry pred  loc   f

Функция: throwErrnoIfMinus1

Описание: выкидывает исключение типа IOError, соответствующее  текущему значению кода ошибки, если заданное действие в монаде IO вернуло значение -1. Определение:

throwErrnoIfMinus1 :: Num  a => String ->  IO  a ->  IO a throwErrnoIfMinus1 =  throwErrnoIf (==  -1)

Функция: throwErrnoIfMinus1-

Описание: вариант функции throwErrnoIfMinus1, который игнорирует результат выполненного действия (используется тогда, когда результат не важен, но важны побочные эффекты монады IO).

Определение:

throwErrnoIfMinus1_ :: Num  a => String ->  IO  a ->  IO () throwErrnoIfMinus1_ =  throwErrnoIf_ (==  -1)

Функция: throwErrnoIfMinus1Retry

Описание: выкидывает исключение типа IOError, соответствующее  текущему значению кода ошибки, если заданное действие в монаде IO вернуло значение -1, однако пытается повторить это действие в случае, если операция была прервана.

Определение:

throwErrnoIfMinus1Retry :: Num  a => String ->  IO a  ->  IO a throwErrnoIfMinus1Retry =  throwErrnoIfRetry  (==  -1)

Функция: throwErrnoIfMinus1Retry-

Описание: вариант функции throwErrnoIfMinus1Retry, который игнорирует результат выполненного действия (используется тогда, когда результат не важен, но важны побочные эффекты монады IO).

Определение:

throwErrnoIfMinus1Retry_ :: Num  a => String ->  IO a  ->  IO () throwErrnoIfMinus1Retry_ =  throwErrnoIfRetry_ (==  -1)

Функция: throwErrnoIfNull

Описание: выкидывает исключение типа IOError, соответствующее  текущему значению кода  ошибки, если заданное действие в монаде IO  вернуло значение nullPtr (пустой указатель).

Определение:

throwErrnoIfNull :: String ->  IO (Ptr a)  ->  IO  (Ptr a) throwErrnoIfNull = throwErrnoIf  (==  nullPtr)

Функция: throwErrnoIfNullRetry

Описание: выкидывает исключение типа IOError, соответствующее  текущему значению кода  ошибки, если заданное действие в монаде IO  вернуло значение nullPtr (пустой указатель), однако пытается повторить это действие в случае, если операция была прервана.

Определение:

throwErrnoIfNullRetry :: String ->  IO (Ptr a)  ->  IO  (Ptr a) throwErrnoIfNullRetry = throwErrnoIfRetry  (==  nullPtr)

Функция: throwErrnoIfRetryMayBlock

Описание: вариант функции throwErrnoIfRetry (см. стр. 425), который проверяет операции, которые могут заблокировать поток управления, и если это произошло, выполняет заданное четвёртым аргументом монадическое действие.

Определение:

throwErrnoIfRetryMayBlock :: (a  ->  Bool)   ->  String ->  IO a ->  IO  b ->  IO a throwErrnoIfRetryMayBlock pred  loc   f on_block

= do res  < f

if pred  res

then  do err  < getErrno if  err  ==  eINTR

then  throwErrnoIfRetryMayBlock pred  loc  f on_block else  if err == eWOULDBLOCK  ||  err == eAGAIN

then  do on_block

throwErrnoIfRetryMayBlock pred  loc  f on_block else  throwErrno loc

else  return res

Функция: throwErrnoIfRetryMayBlock-

Описание: вариант функции throwErrnoIfRetryMayBlock, который  игнорирует результат выполненного действия (используется тогда, когда результат не важен, но важны побочные эффекты монады IO).

Определение:

throwErrnoIfRetryMayBlock_ :: (a  ->  Bool)   ->  String ->  IO a ->  IO  b ->  IO () throwErrnoIfRetryMayBlock_ pred  loc   f on_block

= void  $ throwErrnoIfRetryMayBlock pred  loc   f on_block

Функция: throwErrnoIfMinus1RetryMayBlock

Описание: вариант функции throwErrnoIfMinus1Retry (см. стр. 426), который проверяет операции, которые могут заблокировать поток управления, и если это произошло, выполняет заданное четвёртым аргументом монадическое действие. Определение:

throwErrnoIfMinus1RetryMayBlock :: Num  a => String ->  IO a ->  IO  b ->  IO a throwErrnoIfMinus1RetryMayBlock =  throwErrnoIfRetryMayBlock (==  -1)

Функция: throwErrnoIfMinus1RetryMayBlock-

Описание: вариант функции tthrowErrnoIfMinus1RetryMayBlock,  который  игнорирует результат выполненного действия (используется тогда, когда результат не важен, но важны побочные эффекты монады IO).

Определение:

throwErrnoIfMinus1RetryMayBlock_ :: Num  a => String ->  IO a ->  IO b  ->  IO () throwErrnoIfMinus1RetryMayBlock_ =  throwErrnoIfRetryMayBlock_ (==  -1)

Функция: throwErrnoIfNullRetryMayBlock

Описание: вариант функции throwErrnoIfNullRetry (см. стр. 427), который проверяет операции, которые  могут заблокировать поток  управления, и если это произошло, выполняет заданное четвёртым аргументом монадическое действие. Определение:

throwErrnoIfNullRetryMayBlock :: String ->  IO (Ptr a)  ->  IO b ->  IO  (Ptr a) throwErrnoIfNullRetryMayBlock = throwErrnoIfRetryMayBlock  (==  nullPtr)

Источник: Душкин Р. В., Справочник по языку Haskell. М.: ДМК Пресс, 2008. 544 с., ил.

По теме:

  • Комментарии