Skip to content

Commit eb815f4

Browse files
committed
options/glibc: implement strerrordesc_np, strerrorname_np
1 parent ce23224 commit eb815f4

File tree

5 files changed

+179
-2
lines changed

5 files changed

+179
-2
lines changed

options/ansi/generic/string-stubs.cpp

Lines changed: 145 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
#ifndef _GNU_SOURCE
2+
#define _GNU_SOURCE
3+
#endif
4+
15
#include <string.h>
26
#include <errno.h>
37
#include <wchar.h>
@@ -341,7 +345,9 @@ wchar_t *wmemset(wchar_t *d, wchar_t c, size_t n) {
341345
return ret;
342346
}
343347

344-
char *strerror(int e) {
348+
namespace {
349+
350+
const char *strerror_base(int e) {
345351
const char *s;
346352
switch(e) {
347353
case EAGAIN: s = "Operation would block (EAGAIN)"; break;
@@ -456,10 +462,21 @@ char *strerror(int e) {
456462
case ERESTART: s = "Interrupted system call should be restarted (ERESTART)"; break;
457463
case EUSERS: s = "Too many users (EUSERS)"; break;
458464
default:
459-
s = "Unknown error code (?)";
465+
s = nullptr;
460466
}
467+
return s;
468+
}
469+
470+
} // anonymous namespace
471+
472+
char *strerror(int e) {
473+
const char *s = strerror_base(e);
474+
if(s == nullptr)
475+
s = "Unknown error code (?)";
476+
461477
return const_cast<char *>(s);
462478
}
479+
463480
// strlen() is defined in options/internals.
464481

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

480497
// GNU extensions.
498+
const char *strerrorname_np(int e) {
499+
const char *s;
500+
#define X(x) case x: s = #x; break;
501+
switch(e) {
502+
X(EAGAIN)
503+
X(EACCES)
504+
X(EBADF)
505+
X(EEXIST)
506+
X(EFAULT)
507+
X(EINTR)
508+
X(EINVAL)
509+
X(EIO)
510+
X(EISDIR)
511+
X(ENOENT)
512+
X(ENOMEM)
513+
X(ENOTDIR)
514+
X(ENOSYS)
515+
X(EPERM)
516+
X(EPIPE)
517+
X(ESPIPE)
518+
X(ENXIO)
519+
X(ENOEXEC)
520+
X(ENOSPC)
521+
X(ENOTSOCK)
522+
X(ENOTCONN)
523+
X(EDOM)
524+
X(EILSEQ)
525+
X(ERANGE)
526+
X(E2BIG)
527+
X(EADDRINUSE)
528+
X(EADDRNOTAVAIL)
529+
X(EAFNOSUPPORT)
530+
X(EALREADY)
531+
X(EBADMSG)
532+
X(EBUSY)
533+
X(ECANCELED)
534+
X(ECHILD)
535+
X(ECONNABORTED)
536+
X(ECONNREFUSED)
537+
X(ECONNRESET)
538+
X(EDEADLK)
539+
X(EDESTADDRREQ)
540+
X(EDQUOT)
541+
X(EFBIG)
542+
X(EHOSTUNREACH)
543+
X(EIDRM)
544+
X(EINPROGRESS)
545+
X(EISCONN)
546+
X(ELOOP)
547+
X(EMFILE)
548+
X(EMLINK)
549+
X(EMSGSIZE)
550+
X(EMULTIHOP)
551+
X(ENAMETOOLONG)
552+
X(ENETDOWN)
553+
X(ENETRESET)
554+
X(ENETUNREACH)
555+
X(ENFILE)
556+
X(ENOBUFS)
557+
X(ENODEV)
558+
X(ENOLCK)
559+
X(ENOLINK)
560+
X(ENOMSG)
561+
X(ENOPROTOOPT)
562+
X(ENOTEMPTY)
563+
X(ENOTRECOVERABLE)
564+
X(ENOTSUP)
565+
X(ENOTTY)
566+
X(EOVERFLOW)
567+
#if EOPNOTSUPP != ENOTSUP
568+
/* these are aliases on the mlibc abi */
569+
X(EOPNOTSUPP)
570+
#endif
571+
X(EOWNERDEAD)
572+
X(EPROTO)
573+
X(EPROTONOSUPPORT)
574+
X(EPROTOTYPE)
575+
X(EROFS)
576+
X(ESRCH)
577+
X(ESTALE)
578+
X(ETIMEDOUT)
579+
X(ETXTBSY)
580+
X(EXDEV)
581+
X(ENODATA)
582+
X(ETIME)
583+
X(ENOKEY)
584+
X(ESHUTDOWN)
585+
X(EHOSTDOWN)
586+
X(EBADFD)
587+
X(ENOMEDIUM)
588+
X(ENOTBLK)
589+
X(ENONET)
590+
X(EPFNOSUPPORT)
591+
X(ESOCKTNOSUPPORT)
592+
X(ESTRPIPE)
593+
X(EREMOTEIO)
594+
X(ERFKILL)
595+
X(EBADR)
596+
X(EUNATCH)
597+
X(EMEDIUMTYPE)
598+
X(EREMOTE)
599+
X(EKEYREJECTED)
600+
X(EUCLEAN)
601+
X(EBADSLT)
602+
X(ENOANO)
603+
X(ENOCSI)
604+
X(ENOSTR)
605+
X(ETOOMANYREFS)
606+
X(ENOPKG)
607+
X(EKEYREVOKED)
608+
X(EXFULL)
609+
X(ELNRNG)
610+
X(ENOTUNIQ)
611+
X(ERESTART)
612+
X(EUSERS)
613+
default:
614+
s = nullptr;
615+
}
616+
#undef X
617+
return s;
618+
}
619+
620+
const char *strerrordesc_np(int e) {
621+
return strerror_base(e);
622+
}
623+
481624
// Taken from musl.
482625
int strverscmp(const char *l0, const char *r0) {
483626
const unsigned char *l = (const unsigned char *)l0;

options/ansi/include/string.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ int strerror_r(int, char *, size_t);
6060
void *mempcpy(void *, const void *, size_t);
6161

6262
// GNU extensions.
63+
#ifdef _GNU_SOURCE
64+
const char *strerrorname_np(int e);
65+
const char *strerrordesc_np(int e);
66+
#endif
6367
int strverscmp(const char *l0, const char *r0);
6468
int ffsl(long i);
6569
int ffsll(long long i);

tests/glibc/strerrordesc.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#ifndef _GNU_SOURCE
2+
#define _GNU_SOURCE
3+
#endif
4+
#include <string.h>
5+
#include <errno.h>
6+
#include <assert.h>
7+
8+
int main(void) {
9+
#if !defined(__GLIBC__) || (__GLIBC__ >= 2 && __GLIBC_MINOR__ >= 32)
10+
const char *s = strerrordesc_np(EINVAL);
11+
assert(!strcmp(s, "Invalid argument (EINVAL)"));
12+
assert(strerrordesc_np(0) == NULL);
13+
#endif
14+
}

tests/glibc/strerrorname.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#ifndef _GNU_SOURCE
2+
#define _GNU_SOURCE
3+
#endif
4+
#include <string.h>
5+
#include <errno.h>
6+
#include <assert.h>
7+
8+
int main(void) {
9+
#if !defined(__GLIBC__) || (__GLIBC__ >= 2 && __GLIBC_MINOR__ >= 32)
10+
const char *s = strerrorname_np(EINVAL);
11+
assert(!strcmp(s, "EINVAL"));
12+
assert(strerrorname_np(0) == NULL);
13+
#endif
14+
}

tests/meson.build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ all_test_cases = [
9696
'glibc/error_expect_fail',
9797
'glibc/error',
9898
'glibc/error_at_line',
99+
'glibc/strerrorname',
100+
'glibc/strerrordesc',
99101
'linux/xattr',
100102
'linux/pthread_setname_np',
101103
'linux/pthread_attr',

0 commit comments

Comments
 (0)