用户定义的 errno 范围值(POSIX 或 Linux-特定)
User-defined errno range values (POSIX or Linux-specific)
如果可能,POSIX 的问题,否则 Linux-特定平台的问题:
- 是否有用户定义的
errno
值?(至于信号SIGUSR1
和SIGUSR2
)
- 如何找到系统未使用的
errno
值?(负值?)
- 如何防止
strerror()
中断?(检查errnum
符号前?)
我的代码open()
一个资源并通知另一个对象。如果发生故障(成功为零),通知 Event
会向系统传达 errno
。
但是也可以在我的代码中检测到失败,例如if(count>=size)
。我想重用字段 Event::errnum
来传达这个失败。因此,我的用户定义的故障代码不应与系统定义的 errno
值重叠。
我找到了errno
range 9000–11000 reserved for user, but this seems to be specific to Transaction Processing Facility...
请注意,我的问题 不是 关于 library-defined errno 的问题。 struct Event
没有暴露在我的代码之外。我的代码不会覆盖 errno
。
下面的代码片段在 c++ but my question also applies for 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++ 标准定义。因此,无法 return 一个特定的(正)整数并保证它不会与实现使用的整数发生冲突。
C标准只需要三个宏:
C11 草稿,7.5 个错误
The macros are
EDOM
EILSEQ
ERANGE
which expand to integer constant expressions with type int, distinct
positive values, and which are suitable for use in #if preprocessing
directives;
所以您不知道在您的实现中定义了哪些其他 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
的类似。
请注意,您还应该在调用 "open-resource" 之前将 errno
设置为 0
,以确保 errno
确实由您的函数设置。
在这种情况下,我会完全避免使用标准 errno 并定义我自己的错误枚举。如果您的 "open-resource" 不太复杂并且 return 也有可能出现错误代码,那么您可以这样做。
建议使用负值作为用户定义的范围。 这对我来说是完美的。
下面是我使用 P.P 的建议的问题片段。此代码段也可在 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
如果可能,POSIX 的问题,否则 Linux-特定平台的问题:
- 是否有用户定义的
errno
值?(至于信号SIGUSR1
和SIGUSR2
) - 如何找到系统未使用的
errno
值?(负值?) - 如何防止
strerror()
中断?(检查errnum
符号前?)
我的代码open()
一个资源并通知另一个对象。如果发生故障(成功为零),通知 Event
会向系统传达 errno
。
但是也可以在我的代码中检测到失败,例如if(count>=size)
。我想重用字段 Event::errnum
来传达这个失败。因此,我的用户定义的故障代码不应与系统定义的 errno
值重叠。
我找到了errno
range 9000–11000 reserved for user, but this seems to be specific to Transaction Processing Facility...
请注意,我的问题 不是 关于 library-defined errno 的问题。 struct Event
没有暴露在我的代码之外。我的代码不会覆盖 errno
。
下面的代码片段在 c++ but my question also applies for 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++ 标准定义。因此,无法 return 一个特定的(正)整数并保证它不会与实现使用的整数发生冲突。
C标准只需要三个宏:
C11 草稿,7.5 个错误
The macros are
EDOM
EILSEQ
ERANGEwhich expand to integer constant expressions with type int, distinct positive values, and which are suitable for use in #if preprocessing directives;
所以您不知道在您的实现中定义了哪些其他 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
的类似。
请注意,您还应该在调用 "open-resource" 之前将 errno
设置为 0
,以确保 errno
确实由您的函数设置。
在这种情况下,我会完全避免使用标准 errno 并定义我自己的错误枚举。如果您的 "open-resource" 不太复杂并且 return 也有可能出现错误代码,那么您可以这样做。
下面是我使用 P.P 的建议的问题片段。此代码段也可在 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