| // SPDX-License-Identifier: GPL-2.0 |
| #include <linux/build_bug.h> |
| #include <linux/errno.h> |
| #include <linux/errname.h> |
| #include <linux/kernel.h> |
| #include <linux/math.h> |
| |
| /* |
| * Ensure these tables do not accidentally become gigantic if some |
| * huge errno makes it in. On most architectures, the first table will |
| * only have about 140 entries, but mips and parisc have more sparsely |
| * allocated errnos (with EHWPOISON = 257 on parisc, and EDQUOT = 1133 |
| * on mips), so this wastes a bit of space on those - though we |
| * special case the EDQUOT case. |
| */ |
| #define E(err) [err + BUILD_BUG_ON_ZERO(err <= 0 || err > 300)] = "-" #err |
| static const char *names_0[] = { |
| E(E2BIG), |
| E(EACCES), |
| E(EADDRINUSE), |
| E(EADDRNOTAVAIL), |
| E(EADV), |
| E(EAFNOSUPPORT), |
| E(EAGAIN), /* EWOULDBLOCK */ |
| E(EALREADY), |
| E(EBADE), |
| E(EBADF), |
| E(EBADFD), |
| E(EBADMSG), |
| E(EBADR), |
| E(EBADRQC), |
| E(EBADSLT), |
| E(EBFONT), |
| E(EBUSY), |
| E(ECANCELED), /* ECANCELLED */ |
| E(ECHILD), |
| E(ECHRNG), |
| E(ECOMM), |
| E(ECONNABORTED), |
| E(ECONNREFUSED), /* EREFUSED */ |
| E(ECONNRESET), |
| E(EDEADLK), /* EDEADLOCK */ |
| #if EDEADLK != EDEADLOCK /* mips, sparc, powerpc */ |
| E(EDEADLOCK), |
| #endif |
| E(EDESTADDRREQ), |
| E(EDOM), |
| E(EDOTDOT), |
| #ifndef CONFIG_MIPS |
| E(EDQUOT), |
| #endif |
| E(EEXIST), |
| E(EFAULT), |
| E(EFBIG), |
| E(EHOSTDOWN), |
| E(EHOSTUNREACH), |
| E(EHWPOISON), |
| E(EIDRM), |
| E(EILSEQ), |
| #ifdef EINIT |
| E(EINIT), |
| #endif |
| E(EINPROGRESS), |
| E(EINTR), |
| E(EINVAL), |
| E(EIO), |
| E(EISCONN), |
| E(EISDIR), |
| E(EISNAM), |
| E(EKEYEXPIRED), |
| E(EKEYREJECTED), |
| E(EKEYREVOKED), |
| E(EL2HLT), |
| E(EL2NSYNC), |
| E(EL3HLT), |
| E(EL3RST), |
| E(ELIBACC), |
| E(ELIBBAD), |
| E(ELIBEXEC), |
| E(ELIBMAX), |
| E(ELIBSCN), |
| E(ELNRNG), |
| E(ELOOP), |
| E(EMEDIUMTYPE), |
| E(EMFILE), |
| E(EMLINK), |
| E(EMSGSIZE), |
| E(EMULTIHOP), |
| E(ENAMETOOLONG), |
| E(ENAVAIL), |
| E(ENETDOWN), |
| E(ENETRESET), |
| E(ENETUNREACH), |
| E(ENFILE), |
| E(ENOANO), |
| E(ENOBUFS), |
| E(ENOCSI), |
| E(ENODATA), |
| E(ENODEV), |
| E(ENOENT), |
| E(ENOEXEC), |
| E(ENOKEY), |
| E(ENOLCK), |
| E(ENOLINK), |
| E(ENOMEDIUM), |
| E(ENOMEM), |
| E(ENOMSG), |
| E(ENONET), |
| E(ENOPKG), |
| E(ENOPROTOOPT), |
| E(ENOSPC), |
| E(ENOSR), |
| E(ENOSTR), |
| E(ENOSYS), |
| E(ENOTBLK), |
| E(ENOTCONN), |
| E(ENOTDIR), |
| E(ENOTEMPTY), |
| E(ENOTNAM), |
| E(ENOTRECOVERABLE), |
| E(ENOTSOCK), |
| E(ENOTTY), |
| E(ENOTUNIQ), |
| E(ENXIO), |
| E(EOPNOTSUPP), |
| E(EOVERFLOW), |
| E(EOWNERDEAD), |
| E(EPERM), |
| E(EPFNOSUPPORT), |
| E(EPIPE), |
| #ifdef EPROCLIM |
| E(EPROCLIM), |
| #endif |
| E(EPROTO), |
| E(EPROTONOSUPPORT), |
| E(EPROTOTYPE), |
| E(ERANGE), |
| E(EREMCHG), |
| #ifdef EREMDEV |
| E(EREMDEV), |
| #endif |
| E(EREMOTE), |
| E(EREMOTEIO), |
| E(ERESTART), |
| E(ERFKILL), |
| E(EROFS), |
| #ifdef ERREMOTE |
| E(ERREMOTE), |
| #endif |
| E(ESHUTDOWN), |
| E(ESOCKTNOSUPPORT), |
| E(ESPIPE), |
| E(ESRCH), |
| E(ESRMNT), |
| E(ESTALE), |
| E(ESTRPIPE), |
| E(ETIME), |
| E(ETIMEDOUT), |
| E(ETOOMANYREFS), |
| E(ETXTBSY), |
| E(EUCLEAN), |
| E(EUNATCH), |
| E(EUSERS), |
| E(EXDEV), |
| E(EXFULL), |
| }; |
| #undef E |
| |
| #ifdef EREFUSED /* parisc */ |
| static_assert(EREFUSED == ECONNREFUSED); |
| #endif |
| #ifdef ECANCELLED /* parisc */ |
| static_assert(ECANCELLED == ECANCELED); |
| #endif |
| static_assert(EAGAIN == EWOULDBLOCK); /* everywhere */ |
| |
| #define E(err) [err - 512 + BUILD_BUG_ON_ZERO(err < 512 || err > 550)] = "-" #err |
| static const char *names_512[] = { |
| E(ERESTARTSYS), |
| E(ERESTARTNOINTR), |
| E(ERESTARTNOHAND), |
| E(ENOIOCTLCMD), |
| E(ERESTART_RESTARTBLOCK), |
| E(EPROBE_DEFER), |
| E(EOPENSTALE), |
| E(ENOPARAM), |
| |
| E(EBADHANDLE), |
| E(ENOTSYNC), |
| E(EBADCOOKIE), |
| E(ENOTSUPP), |
| E(ETOOSMALL), |
| E(ESERVERFAULT), |
| E(EBADTYPE), |
| E(EJUKEBOX), |
| E(EIOCBQUEUED), |
| E(ERECALLCONFLICT), |
| }; |
| #undef E |
| |
| static const char *__errname(unsigned err) |
| { |
| if (err < ARRAY_SIZE(names_0)) |
| return names_0[err]; |
| if (err >= 512 && err - 512 < ARRAY_SIZE(names_512)) |
| return names_512[err - 512]; |
| /* But why? */ |
| if (IS_ENABLED(CONFIG_MIPS) && err == EDQUOT) /* 1133 */ |
| return "-EDQUOT"; |
| return NULL; |
| } |
| |
| /* |
| * errname(EIO) -> "EIO" |
| * errname(-EIO) -> "-EIO" |
| */ |
| const char *errname(int err) |
| { |
| const char *name = __errname(abs(err)); |
| if (!name) |
| return NULL; |
| |
| return err > 0 ? name + 1 : name; |
| } |
| EXPORT_SYMBOL(errname); |