Questions for POSIX if possible, else for Linux-specific platforms:
errno
values? (as for signals SIGUSR1
and SIGUSR2
)errno
value not used by the system? (negative values?)strerror()
break? (check before the errnum
sign?)My code open()
a resource and notifies another object. The notification Event
conveys the system errno
if a failure occurs (zero on success).
But failures can also be detected in my code, e.g. if(count>=size)
. And I want to reuse the field Event::errnum
to convey this failure. Therefore my user-defined failure code should not overlap system-defined errno
values.
I have found errno
range 9000–11000 reserved for user, but this seems to be specific to Transaction Processing Facility...
Note my question is not about library-defined errno. The struct Event
is not exposed outside my code. My code does not overwrite errno
.
Below snippet is in 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...
}
The actual errno
values are not defined by the C and C++ standards. So there's no way to return a particular (positive) integer and guarantee it to not clash with the one that an implementation uses.
The C standard requires only three marco:
C11 draft, 7.5 Errors
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;
So you don't know what other errno
values are defined in your implementation.
The errno
values are postive integers in standard C and POSIX. So you could use your own enumaration with negative values to define your own error numbers.
But then you can't use the strerror/perror interfaces. So you may need additional wrapper for strerror/perror to interpret your own error numbers.
Something like:
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);
}
and a similar one for perror
.
Note you should also set errno
to 0
before calling your "open-resource" to make sure the errno
was indeed set by your function.
I'd avoid the standard errno altogether in situations like this and define my own enumeration for errors. You could do that if your "open-resource" is not too complicated and returns too possible error codes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With