User-defined range errno values ​​(POSIX or Linux)

Questions for POSIX, if applicable, and Linux-specific platforms:

  • Are there custom values errno

    ?
    (as for signals SIGUSR1

    and SIGUSR2

    )
  • How do I find a value errno

    not used by the system?
    (negative values?)
  • How to prevent strerror()

    break?
    (check before the sign errnum

    ?)

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 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...
}

      

+6


source to share


2 answers


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
ERANGE

which 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.

+2


source


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

      

0


source







All Articles