sdaau
sdaau

Reputation: 38651

Print errno as mnemonic?

I have seen Symbolic errno to String - Stack Overflow, so even if that question is bash related, I can already tell that this isn't trivial; but just to confirm:

Is there a C API function, which like strerror() will accept the numeric errno as argument - but which will print the mnemonic (e.g. EINVAL) instead of the error description string (e.g. "Invalid argument")?

As an example, I'd like

printf("Number: %d (%s): '%s'\n", 22, strerror_mnemonic(22), strerror(22) );

... to print:

Number: 22 (EINVAL): 'Invalid argument'

... where strerror_mnemonic is pseudocode for the C function I'm looking for.

Upvotes: 6

Views: 751

Answers (5)

the kamilz
the kamilz

Reputation: 1988

Here is the function that returns errno as mnemonic: https://paste.ubuntu.com/26170061/

Thank me later.

Upvotes: 1

user3125367
user3125367

Reputation: 3000

What's the problem?

perl -ne 'print "$1\n" if /^#\s*define\s+(E[A-Z0-9]+)/' < /usr/include/sys/errno.h | sort | uniq | perl -ne 'chomp; print "    { $_, \"$_\" }\n"'

This unix shell command printa out E* defines from /usr/include/sys/errno.h (where actual defines live) in form { EINVAL, "EINVAL" },. You may then wrap it into an array:

struct errno_str_t {
    int code;
    const char *str;
} errnos[] = {
    { EINVAL, "EINVAL" },
    ...
};

And sort by errno value at runtime if needed. If you want to be portable (to some extent), consider making this a part of build process. Do not worry, that's the true unix way of doing this :)

Upvotes: 2

ecatmur
ecatmur

Reputation: 157444

Unfortunately not; there is no introspection support for the E error macros.

You can do this trivially in Python:

import errno
print(errno.errorcode[errno.EPERM])

This is because the Python maintainers have gone to the trouble of generating a lookup table: http://hg.python.org/cpython/file/tip/Modules/errnomodule.c

Upvotes: 2

abligh
abligh

Reputation: 25169

The second part of your question is answered by strerror (as you point out), or better strerror_r, but in glibc at least you can simply use %m as a format specifier.

The first part is more interesting, i.e. how do you get the name of the C constant for the error. I believe there is no way to do that using standard glibc. You could construct your own static array or hash table to do this relatively easily.

Upvotes: 4

You want strerror(3). You may sometimes be interested by perror(3). BTW, the errno(3) man page mentions them.

You probably don't need to display the EINVAL mnemonic (unless you care about C code generation). If you did, make a function for that (essentially, a switch statement).

Upvotes: 1

Related Questions