Skip to content

Commit

Permalink
options/glibc: implement strerrordesc_np, strerrorname_np
Browse files Browse the repository at this point in the history
  • Loading branch information
ikbenlike committed Aug 10, 2023
1 parent ce23224 commit eb815f4
Show file tree
Hide file tree
Showing 5 changed files with 179 additions and 2 deletions.
147 changes: 145 additions & 2 deletions options/ansi/generic/string-stubs.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif

#include <string.h>
#include <errno.h>
#include <wchar.h>
Expand Down Expand Up @@ -341,7 +345,9 @@ wchar_t *wmemset(wchar_t *d, wchar_t c, size_t n) {
return ret;
}

char *strerror(int e) {
namespace {

const char *strerror_base(int e) {
const char *s;
switch(e) {
case EAGAIN: s = "Operation would block (EAGAIN)"; break;
Expand Down Expand Up @@ -456,10 +462,21 @@ char *strerror(int e) {
case ERESTART: s = "Interrupted system call should be restarted (ERESTART)"; break;
case EUSERS: s = "Too many users (EUSERS)"; break;
default:
s = "Unknown error code (?)";
s = nullptr;
}
return s;
}

} // anonymous namespace

char *strerror(int e) {
const char *s = strerror_base(e);
if(s == nullptr)
s = "Unknown error code (?)";

return const_cast<char *>(s);
}

// strlen() is defined in options/internals.

// POSIX extensions.
Expand All @@ -478,6 +495,132 @@ void *mempcpy(void *dest, const void *src, size_t len) {
}

// GNU extensions.
const char *strerrorname_np(int e) {
const char *s;
#define X(x) case x: s = #x; break;
switch(e) {
X(EAGAIN)
X(EACCES)
X(EBADF)
X(EEXIST)
X(EFAULT)
X(EINTR)
X(EINVAL)
X(EIO)
X(EISDIR)
X(ENOENT)
X(ENOMEM)
X(ENOTDIR)
X(ENOSYS)
X(EPERM)
X(EPIPE)
X(ESPIPE)
X(ENXIO)
X(ENOEXEC)
X(ENOSPC)
X(ENOTSOCK)
X(ENOTCONN)
X(EDOM)
X(EILSEQ)
X(ERANGE)
X(E2BIG)
X(EADDRINUSE)
X(EADDRNOTAVAIL)
X(EAFNOSUPPORT)
X(EALREADY)
X(EBADMSG)
X(EBUSY)
X(ECANCELED)
X(ECHILD)
X(ECONNABORTED)
X(ECONNREFUSED)
X(ECONNRESET)
X(EDEADLK)
X(EDESTADDRREQ)
X(EDQUOT)
X(EFBIG)
X(EHOSTUNREACH)
X(EIDRM)
X(EINPROGRESS)
X(EISCONN)
X(ELOOP)
X(EMFILE)
X(EMLINK)
X(EMSGSIZE)
X(EMULTIHOP)
X(ENAMETOOLONG)
X(ENETDOWN)
X(ENETRESET)
X(ENETUNREACH)
X(ENFILE)
X(ENOBUFS)
X(ENODEV)
X(ENOLCK)
X(ENOLINK)
X(ENOMSG)
X(ENOPROTOOPT)
X(ENOTEMPTY)
X(ENOTRECOVERABLE)
X(ENOTSUP)
X(ENOTTY)
X(EOVERFLOW)
#if EOPNOTSUPP != ENOTSUP
/* these are aliases on the mlibc abi */
X(EOPNOTSUPP)
#endif
X(EOWNERDEAD)
X(EPROTO)
X(EPROTONOSUPPORT)
X(EPROTOTYPE)
X(EROFS)
X(ESRCH)
X(ESTALE)
X(ETIMEDOUT)
X(ETXTBSY)
X(EXDEV)
X(ENODATA)
X(ETIME)
X(ENOKEY)
X(ESHUTDOWN)
X(EHOSTDOWN)
X(EBADFD)
X(ENOMEDIUM)
X(ENOTBLK)
X(ENONET)
X(EPFNOSUPPORT)
X(ESOCKTNOSUPPORT)
X(ESTRPIPE)
X(EREMOTEIO)
X(ERFKILL)
X(EBADR)
X(EUNATCH)
X(EMEDIUMTYPE)
X(EREMOTE)
X(EKEYREJECTED)
X(EUCLEAN)
X(EBADSLT)
X(ENOANO)
X(ENOCSI)
X(ENOSTR)
X(ETOOMANYREFS)
X(ENOPKG)
X(EKEYREVOKED)
X(EXFULL)
X(ELNRNG)
X(ENOTUNIQ)
X(ERESTART)
X(EUSERS)
default:
s = nullptr;
}
#undef X
return s;
}

const char *strerrordesc_np(int e) {
return strerror_base(e);
}

// Taken from musl.
int strverscmp(const char *l0, const char *r0) {
const unsigned char *l = (const unsigned char *)l0;
Expand Down
4 changes: 4 additions & 0 deletions options/ansi/include/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ int strerror_r(int, char *, size_t);
void *mempcpy(void *, const void *, size_t);

// GNU extensions.
#ifdef _GNU_SOURCE
const char *strerrorname_np(int e);
const char *strerrordesc_np(int e);
#endif
int strverscmp(const char *l0, const char *r0);
int ffsl(long i);
int ffsll(long long i);
Expand Down
14 changes: 14 additions & 0 deletions tests/glibc/strerrordesc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <string.h>
#include <errno.h>
#include <assert.h>

int main(void) {
#if !defined(__GLIBC__) || (__GLIBC__ >= 2 && __GLIBC_MINOR__ >= 32)
const char *s = strerrordesc_np(EINVAL);
assert(!strcmp(s, "Invalid argument (EINVAL)"));
assert(strerrordesc_np(0) == NULL);
#endif
}
14 changes: 14 additions & 0 deletions tests/glibc/strerrorname.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <string.h>
#include <errno.h>
#include <assert.h>

int main(void) {
#if !defined(__GLIBC__) || (__GLIBC__ >= 2 && __GLIBC_MINOR__ >= 32)
const char *s = strerrorname_np(EINVAL);
assert(!strcmp(s, "EINVAL"));
assert(strerrorname_np(0) == NULL);
#endif
}
2 changes: 2 additions & 0 deletions tests/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ all_test_cases = [
'glibc/error_expect_fail',
'glibc/error',
'glibc/error_at_line',
'glibc/strerrorname',
'glibc/strerrordesc',
'linux/xattr',
'linux/pthread_setname_np',
'linux/pthread_attr',
Expand Down

0 comments on commit eb815f4

Please sign in to comment.