Подтвердить что ты не робот

Должен ли я установить errno?

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

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

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

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

4b9b3361

Ответ 1

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

Ответ 2

Вы можете не только установить 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. [Option End]

Ответ 3

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

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

enum myerrors {
    ERR_NO_MEMORY    = -1,
    ERR_BAD_ARGS     = -2,
    ERR_CPU_EXPLODED = -3,
    // and so on
};

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

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

Ответ 4

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

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