Вопросы для POSIX, если это возможно, иначе для платформ, специфичных для Linux:
errno
ценности? (что касается сигналов SIGUSR1
а также SIGUSR2
)errno
значение не используется системой? (отрицательные значения?)strerror()
перерыв? (проверьте перед errnum
знак?)Мой код open()
ресурс и уведомляет другой объект. Уведомление Event
передает систему errno
если происходит сбой (ноль при успехе).
Но ошибки также могут быть обнаружены в моем коде, например, if(count>=size)
, И я хочу повторно использовать поле Event::errnum
передать эту неудачу. Поэтому мой определяемый пользователем код ошибки не должен перекрывать системный errno
ценности.
я нашел errno
диапазон 9000–11000 зарезервирован для пользователя, но это, кажется, специфично для Средство обработки транзакций…
Обратите внимание, мой вопрос не около определенный библиотекой errno. struct Event
не выставляется вне моего кода. Мой код не перезаписывается errno
,
Ниже приведен фрагмент C ++ но мой вопрос также относится к с.
#include <cerrno>
#define E_MY_USER_DEFINED_ERROR 9999
struct Event
{
int fd;
int errnum;
};
struct Foo
{
Foo( int sz ) : count(0), size(sz) {}
Event open( const char name[] )
{
if( count >= size )
return { -1, E_MY_USER_DEFINED_ERROR };
int fd = 1; // TODO: open ressource...
if (fd < 0) return { -1, errno };
else return { fd, 0 };
}
int count, size;
};
int main()
{
Foo bar(0);
Event e = bar.open("my-ressource");
// send Event to another object...
}
Настоящий errno
значения не определены стандартами C и C ++. Таким образом, нет способа вернуть определенное (положительное) целое число и гарантировать, что оно не будет конфликтовать с тем, которое использует реализация.
Стандарт C требует только три марко:
C11 осадка, 7,5 ошибок
Макросы
EDOM
EILSEQ
ERANGEкоторые расширяются до целочисленных константных выражений с типом int, отличный
положительные значения и которые подходят для использования при предварительной обработке #if
директивы;
Так что вы не знаете, что другое errno
значения определены в вашей реализации.
errno
значения являются положительными целыми числами в стандарте C и POSIX. Таким образом, вы можете использовать свое собственное перечисление с отрицательными значениями, чтобы определить свои собственные числа ошибок.
Но тогда вы не можете использовать интерфейсы strerror / perror. Поэтому вам может понадобиться дополнительная оболочка для strerror / perror для интерпретации ваших собственных номеров ошибок.
Что-то вроде:
enum myErrors{
ERR1 = -1,
ERR2 = -2,
...
ERR64 = -64
};
char *my_strerror(int e)
{
if (e>=ERR1 && e<=ERR2)
return decode_myerror(e); // decode_myerror can have a map for
//your error numbers and return string representing 'e'.
else
return strerror(e);
}
и аналогичный для perror
,
Обратите внимание, вы также должны установить errno
в 0
перед вызовом вашего «открытого ресурса», чтобы убедиться, что errno
был действительно установлен вашей функцией.
Я бы вообще избегал стандартного errno в подобных ситуациях и определял бы собственное перечисление для ошибок. Вы можете сделать это, если ваш «открытый ресурс» не слишком сложен и возвращает слишком возможные коды ошибок.
Ответ Голубой Луны предлагает использовать отрицательное значение в качестве пользовательского диапазона. Это идеально в моем случае.
Ниже приведен фрагмент моего вопроса с использованием его предложения. Этот фрагмент также доступен на coliru.
#include <cerrno>
#include <cstring>
#include <iostream>
#define E_MY_USER_DEFINED_ERROR -1
struct Event
{
int fd;
int errnum;
};
struct Foo
{
Foo( int sz ) : count(0), size(sz) {}
Event open( const char name[] )
{
if( count >= size )
return { -1, E_MY_USER_DEFINED_ERROR };
int fd = std::strlen(name); // TODO: open ressource...
if (fd < 0) return { -1, errno };
else return { fd, 0 };
}
int count, size;
};
int main()
{
Foo bar(0);
Event e = bar.open("my-ressource");
std::cout << std::strerror( e.errnum ) << std::endl;
}
Вывод с использованием GCC
Unknown error -1
Вывод с использованием Clang
Unknown error -1