Skip to content

Commit 20c55c0

Browse files
committed
options/glibc: implement strerrordesc_np, strerrorname_np
1 parent ca133ca commit 20c55c0

File tree

5 files changed

+175
-2
lines changed

5 files changed

+175
-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>
@@ -337,7 +341,9 @@ wchar_t *wmemset(wchar_t *d, wchar_t c, size_t n) {
337341
return ret;
338342
}
339343

340-
char *strerror(int e) {
344+
namespace {
345+
346+
const char *strerror_base(int e) {
341347
const char *s;
342348
switch(e) {
343349
case EAGAIN: s = "Operation would block (EAGAIN)"; break;
@@ -452,10 +458,21 @@ char *strerror(int e) {
452458
case ERESTART: s = "Interrupted system call should be restarted (ERESTART)"; break;
453459
case EUSERS: s = "Too many users (EUSERS)"; break;
454460
default:
455-
s = "Unknown error code (?)";
461+
s = nullptr;
456462
}
463+
return s;
464+
}
465+
466+
} // anonymous namespace
467+
468+
char *strerror(int e) {
469+
const char *s = strerror_base(e);
470+
if(s == nullptr)
471+
s = "Unknown error code (?)";
472+
457473
return const_cast<char *>(s);
458474
}
475+
459476
// strlen() is defined in options/internals.
460477

461478
// POSIX extensions.
@@ -474,6 +491,132 @@ void *mempcpy(void *dest, const void *src, size_t len) {
474491
}
475492

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

tests/glibc/strerrorname.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
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+
const char *s = strerrorname_np(EINVAL);
10+
assert(!strcmp(s, "EINVAL"));
11+
assert(strerrorname_np(0) == NULL);
12+
}

tests/meson.build

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

0 commit comments

Comments
 (0)