User-defined range errno values ββ(POSIX or Linux)
Questions for POSIX, if applicable, and Linux-specific platforms:
- Are there custom values
errno
? (as for signalsSIGUSR1
andSIGUSR2
) - How do I find a value
errno
not used by the system? (negative values?) - How to prevent
strerror()
break? (check before the signerrnum
?)
My code is a open()
resource and notifies another object. A notification Event
is sent to the system errno
if a failure occurs (zero on success).
But errors can also be found in my code for example. if(count>=size)
... And I want to reuse the field Event::errnum
to pass this failure. Therefore my custom failure code should not overlap the system values errno
.
I found the errno
range 9000-11000 is reserved for the user , but this seems to be specific to the Transaction Processing Object ...
Note that my question is not about library-specific errno . struct Event
doesn't show up outside of my code. My code doesn't overwrite errno
.
Below the snippet is C ++but my question is also applicable 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...
}
source to share
Actual values ββare errno
not defined by the C and C ++ standards. So there is no way to return a specific (positive) integer and ensure that it doesn't collide with the one the implementation is using. The C standard only requires three marks:
C11 draft, 7.5 Bugs
Macros
EDOM
EILSEQ
ERANGEwhich expand to integer constant expressions of type int, positive values ββand which are suitable for use in #if preprocessing directives;
So, you don't know what other values ββare errno
defined in your implementation.
Values errno
are hollow integers in standard C and POSIX. Thus, you can use your own enumeration with negative values ββto define your own error numbers. But then you cannot use strerror / perror interfaces. Therefore, you may need an extra 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 similar for perror
.
Note that you must also set errno
to 0
before naming your "open source" to make sure the feature is errno
actually set by your function.
I would avoid the standard errno in situations like this and define my own error enumeration. This can be done if your "open source" is not too complex and returns too possible error codes.
source to share
P.P. The answer suggests using a negative value as a custom range. This is fine in my case.
Below is a fragment of my question on the proposal of P.P. This snippet is also available at 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;
}
Inference using GCC
Unknown error -1
Output using Clang
Unknown error -1
source to share