Должен ли я установить errno? - PullRequest
41 голосов
/ 25 марта 2012

Я пишу модуль, который экспортирует интерфейс, аналогичный send и recv.

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

В такой ситуации я должен установить errno как стандартная библиотека? Если это так, поскольку errno является специфичным для потока, существует ли особый способ записи на него или я могу просто присвоить ему значение?

Редактировать: экспериментируя, я заметил, что настройка errno по назначению работает. Тем не менее: это безопасно и портативно для любой системы?

Ответы [ 6 ]

32 голосов
/ 25 марта 2012

Это немного устарело, но errno - ручной раздел 3 говорит, что вы можете напрямую назначить ему, даже если это макрос, и он будет локальным для потока

17 голосов
/ 05 июля 2012

Не только может установить errno, во многих случаях следует установить errno. При вызове некоторых библиотечных функций вы можете надежно обнаружить ошибку, только если сначала установите errno в ноль. См. strtol для примера .

Из спецификации POSIX strtol:

[CX] [Option Start] Функция strtol () не должна изменять настройку errno в случае успеха.

Так как 0, {LONG_MIN} или {LLONG_MIN} и {LONG_MAX} или {LLONG_MAX} возвращаются при ошибке и также являются допустимыми возвратами в случае успеха, приложение, желающее проверить наличие ошибок, должно установить для errno значение 0, а затем вызвать strtol () или strtoll (), затем проверьте errno. [Конец опции]

8 голосов
/ 25 марта 2012

На самом деле, вы, вероятно, можете сделать "правильное" (как вы выразились) управление ошибками, поскольку вы возвращаете int.

Просто используйте неотрицательные значения для количества прочитанных или записанных байтов и отрицательные значения для кодов ошибок. У вас нет , чтобы ограничивать себя -1:

* * 1010

Тем не менее, установка errno в желаемом вами стиле действительна. Стандарт гласит, что errno расширяется до модифицируемого lvalue, то есть вы можете установить его. От C1x/n1425, 7.5 Errors <errno.h>:

... и errno, который расширяется до модифицируемого lvalue, имеющего тип int, значение которого устанавливается положительным числом ошибки несколькими библиотечными функциями.

6 голосов
/ 25 марта 2012

Вы можете просто присвоить значение errno, но имейте в виду, что есть и другие способы сообщить об ошибке, которые, в зависимости от вашей ситуации, могут быть более подходящими:

  1. Невернуть количество прочитанных байтов, но вместо этого иметь выходной параметр с типом int * (или size_t * или что вы используете).Затем вы можете вернуть код ошибки.
  2. Предполагая, что ваш тип возвращаемого значения является типом со знаком и что отрицательное количество отправленных или полученных байтов не имеет смысла, используйте отрицательные значения для сигнализации соответствующих условий ошибки.*
2 голосов
/ 25 марта 2012

Да, вы можете назначить ему, и да, назначение будет поточно-ориентированным.См. Является ли errno поточно-ориентированным?

2 голосов
/ 25 марта 2012

От: http://support.sas.com/documentation/onlinedoc/sasc/doc700/html/lr1/errno.htm

Единственными переносимыми значениями для errno являются EDOM и ERANGE

Так что это отвечает на ваш вопрос о переносимости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...