Skip to content

Commit 5d6c4e2

Browse files
committed
options/glibc: implement strerrordesc_np, strerrorname_np
1 parent f08fbe1 commit 5d6c4e2

File tree

5 files changed

+173
-2
lines changed

5 files changed

+173
-2
lines changed

options/ansi/generic/string.cpp

Lines changed: 141 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,9 @@ wchar_t *wmemset(wchar_t *d, wchar_t c, size_t n) {
343343
return ret;
344344
}
345345

346-
char *strerror(int e) {
346+
namespace {
347+
348+
const char *strerror_base(int e) {
347349
const char *s;
348350
switch(e) {
349351
case EAGAIN: s = "Operation would block (EAGAIN)"; break;
@@ -463,10 +465,21 @@ char *strerror(int e) {
463465
#endif
464466

465467
default:
466-
s = "Unknown error code (?)";
468+
s = nullptr;
467469
}
470+
return s;
471+
}
472+
473+
} // anonymous namespace
474+
475+
char *strerror(int e) {
476+
const char *s = strerror_base(e);
477+
if(s == nullptr)
478+
s = "Unknown error code (?)";
479+
468480
return const_cast<char *>(s);
469481
}
482+
470483
// strlen() is defined in options/internals.
471484

472485
extern "C" char *__gnu_strerror_r(int e, char *buffer, size_t bufsz) {
@@ -491,6 +504,132 @@ void *mempcpy(void *dest, const void *src, size_t len) {
491504
}
492505

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

options/ansi/include/string.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ size_t strlen(const char *__s);
6161

6262
/* POSIX extensions. */
6363
#if defined(_GNU_SOURCE)
64+
const char *strerrorname_np(int e);
65+
const char *strerrordesc_np(int e);
6466
char *strerror_r(int __errnum, char *__buffer, size_t __size) __asm__("__gnu_strerror_r");
6567
#else
6668
int strerror_r(int __errnum, char *__buffer, size_t __size);

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
@@ -114,6 +114,8 @@ all_test_cases = [
114114
'glibc/error_at_line',
115115
'glibc/getgrouplist',
116116
'glibc/rpmatch',
117+
'glibc/strerrorname',
118+
'glibc/strerrordesc',
117119
'linux/xattr',
118120
'linux/pthread_setname_np',
119121
'linux/pthread_attr',

0 commit comments

Comments
 (0)