1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun #include <linux/build_bug.h>
3*4882a593Smuzhiyun #include <linux/errno.h>
4*4882a593Smuzhiyun #include <linux/errname.h>
5*4882a593Smuzhiyun #include <linux/kernel.h>
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun /*
8*4882a593Smuzhiyun * Ensure these tables do not accidentally become gigantic if some
9*4882a593Smuzhiyun * huge errno makes it in. On most architectures, the first table will
10*4882a593Smuzhiyun * only have about 140 entries, but mips and parisc have more sparsely
11*4882a593Smuzhiyun * allocated errnos (with EHWPOISON = 257 on parisc, and EDQUOT = 1133
12*4882a593Smuzhiyun * on mips), so this wastes a bit of space on those - though we
13*4882a593Smuzhiyun * special case the EDQUOT case.
14*4882a593Smuzhiyun */
15*4882a593Smuzhiyun #define E(err) [err + BUILD_BUG_ON_ZERO(err <= 0 || err > 300)] = "-" #err
16*4882a593Smuzhiyun static const char *names_0[] = {
17*4882a593Smuzhiyun E(E2BIG),
18*4882a593Smuzhiyun E(EACCES),
19*4882a593Smuzhiyun E(EADDRINUSE),
20*4882a593Smuzhiyun E(EADDRNOTAVAIL),
21*4882a593Smuzhiyun E(EADV),
22*4882a593Smuzhiyun E(EAFNOSUPPORT),
23*4882a593Smuzhiyun E(EALREADY),
24*4882a593Smuzhiyun E(EBADE),
25*4882a593Smuzhiyun E(EBADF),
26*4882a593Smuzhiyun E(EBADFD),
27*4882a593Smuzhiyun E(EBADMSG),
28*4882a593Smuzhiyun E(EBADR),
29*4882a593Smuzhiyun E(EBADRQC),
30*4882a593Smuzhiyun E(EBADSLT),
31*4882a593Smuzhiyun E(EBFONT),
32*4882a593Smuzhiyun E(EBUSY),
33*4882a593Smuzhiyun #ifdef ECANCELLED
34*4882a593Smuzhiyun E(ECANCELLED),
35*4882a593Smuzhiyun #endif
36*4882a593Smuzhiyun E(ECHILD),
37*4882a593Smuzhiyun E(ECHRNG),
38*4882a593Smuzhiyun E(ECOMM),
39*4882a593Smuzhiyun E(ECONNABORTED),
40*4882a593Smuzhiyun E(ECONNRESET),
41*4882a593Smuzhiyun E(EDEADLOCK),
42*4882a593Smuzhiyun E(EDESTADDRREQ),
43*4882a593Smuzhiyun E(EDOM),
44*4882a593Smuzhiyun E(EDOTDOT),
45*4882a593Smuzhiyun #ifndef CONFIG_MIPS
46*4882a593Smuzhiyun E(EDQUOT),
47*4882a593Smuzhiyun #endif
48*4882a593Smuzhiyun E(EEXIST),
49*4882a593Smuzhiyun E(EFAULT),
50*4882a593Smuzhiyun E(EFBIG),
51*4882a593Smuzhiyun E(EHOSTDOWN),
52*4882a593Smuzhiyun E(EHOSTUNREACH),
53*4882a593Smuzhiyun E(EHWPOISON),
54*4882a593Smuzhiyun E(EIDRM),
55*4882a593Smuzhiyun E(EILSEQ),
56*4882a593Smuzhiyun #ifdef EINIT
57*4882a593Smuzhiyun E(EINIT),
58*4882a593Smuzhiyun #endif
59*4882a593Smuzhiyun E(EINPROGRESS),
60*4882a593Smuzhiyun E(EINTR),
61*4882a593Smuzhiyun E(EINVAL),
62*4882a593Smuzhiyun E(EIO),
63*4882a593Smuzhiyun E(EISCONN),
64*4882a593Smuzhiyun E(EISDIR),
65*4882a593Smuzhiyun E(EISNAM),
66*4882a593Smuzhiyun E(EKEYEXPIRED),
67*4882a593Smuzhiyun E(EKEYREJECTED),
68*4882a593Smuzhiyun E(EKEYREVOKED),
69*4882a593Smuzhiyun E(EL2HLT),
70*4882a593Smuzhiyun E(EL2NSYNC),
71*4882a593Smuzhiyun E(EL3HLT),
72*4882a593Smuzhiyun E(EL3RST),
73*4882a593Smuzhiyun E(ELIBACC),
74*4882a593Smuzhiyun E(ELIBBAD),
75*4882a593Smuzhiyun E(ELIBEXEC),
76*4882a593Smuzhiyun E(ELIBMAX),
77*4882a593Smuzhiyun E(ELIBSCN),
78*4882a593Smuzhiyun E(ELNRNG),
79*4882a593Smuzhiyun E(ELOOP),
80*4882a593Smuzhiyun E(EMEDIUMTYPE),
81*4882a593Smuzhiyun E(EMFILE),
82*4882a593Smuzhiyun E(EMLINK),
83*4882a593Smuzhiyun E(EMSGSIZE),
84*4882a593Smuzhiyun E(EMULTIHOP),
85*4882a593Smuzhiyun E(ENAMETOOLONG),
86*4882a593Smuzhiyun E(ENAVAIL),
87*4882a593Smuzhiyun E(ENETDOWN),
88*4882a593Smuzhiyun E(ENETRESET),
89*4882a593Smuzhiyun E(ENETUNREACH),
90*4882a593Smuzhiyun E(ENFILE),
91*4882a593Smuzhiyun E(ENOANO),
92*4882a593Smuzhiyun E(ENOBUFS),
93*4882a593Smuzhiyun E(ENOCSI),
94*4882a593Smuzhiyun E(ENODATA),
95*4882a593Smuzhiyun E(ENODEV),
96*4882a593Smuzhiyun E(ENOENT),
97*4882a593Smuzhiyun E(ENOEXEC),
98*4882a593Smuzhiyun E(ENOKEY),
99*4882a593Smuzhiyun E(ENOLCK),
100*4882a593Smuzhiyun E(ENOLINK),
101*4882a593Smuzhiyun E(ENOMEDIUM),
102*4882a593Smuzhiyun E(ENOMEM),
103*4882a593Smuzhiyun E(ENOMSG),
104*4882a593Smuzhiyun E(ENONET),
105*4882a593Smuzhiyun E(ENOPKG),
106*4882a593Smuzhiyun E(ENOPROTOOPT),
107*4882a593Smuzhiyun E(ENOSPC),
108*4882a593Smuzhiyun E(ENOSR),
109*4882a593Smuzhiyun E(ENOSTR),
110*4882a593Smuzhiyun #ifdef ENOSYM
111*4882a593Smuzhiyun E(ENOSYM),
112*4882a593Smuzhiyun #endif
113*4882a593Smuzhiyun E(ENOSYS),
114*4882a593Smuzhiyun E(ENOTBLK),
115*4882a593Smuzhiyun E(ENOTCONN),
116*4882a593Smuzhiyun E(ENOTDIR),
117*4882a593Smuzhiyun E(ENOTEMPTY),
118*4882a593Smuzhiyun E(ENOTNAM),
119*4882a593Smuzhiyun E(ENOTRECOVERABLE),
120*4882a593Smuzhiyun E(ENOTSOCK),
121*4882a593Smuzhiyun E(ENOTTY),
122*4882a593Smuzhiyun E(ENOTUNIQ),
123*4882a593Smuzhiyun E(ENXIO),
124*4882a593Smuzhiyun E(EOPNOTSUPP),
125*4882a593Smuzhiyun E(EOVERFLOW),
126*4882a593Smuzhiyun E(EOWNERDEAD),
127*4882a593Smuzhiyun E(EPERM),
128*4882a593Smuzhiyun E(EPFNOSUPPORT),
129*4882a593Smuzhiyun E(EPIPE),
130*4882a593Smuzhiyun #ifdef EPROCLIM
131*4882a593Smuzhiyun E(EPROCLIM),
132*4882a593Smuzhiyun #endif
133*4882a593Smuzhiyun E(EPROTO),
134*4882a593Smuzhiyun E(EPROTONOSUPPORT),
135*4882a593Smuzhiyun E(EPROTOTYPE),
136*4882a593Smuzhiyun E(ERANGE),
137*4882a593Smuzhiyun E(EREMCHG),
138*4882a593Smuzhiyun #ifdef EREMDEV
139*4882a593Smuzhiyun E(EREMDEV),
140*4882a593Smuzhiyun #endif
141*4882a593Smuzhiyun E(EREMOTE),
142*4882a593Smuzhiyun E(EREMOTEIO),
143*4882a593Smuzhiyun #ifdef EREMOTERELEASE
144*4882a593Smuzhiyun E(EREMOTERELEASE),
145*4882a593Smuzhiyun #endif
146*4882a593Smuzhiyun E(ERESTART),
147*4882a593Smuzhiyun E(ERFKILL),
148*4882a593Smuzhiyun E(EROFS),
149*4882a593Smuzhiyun #ifdef ERREMOTE
150*4882a593Smuzhiyun E(ERREMOTE),
151*4882a593Smuzhiyun #endif
152*4882a593Smuzhiyun E(ESHUTDOWN),
153*4882a593Smuzhiyun E(ESOCKTNOSUPPORT),
154*4882a593Smuzhiyun E(ESPIPE),
155*4882a593Smuzhiyun E(ESRCH),
156*4882a593Smuzhiyun E(ESRMNT),
157*4882a593Smuzhiyun E(ESTALE),
158*4882a593Smuzhiyun E(ESTRPIPE),
159*4882a593Smuzhiyun E(ETIME),
160*4882a593Smuzhiyun E(ETIMEDOUT),
161*4882a593Smuzhiyun E(ETOOMANYREFS),
162*4882a593Smuzhiyun E(ETXTBSY),
163*4882a593Smuzhiyun E(EUCLEAN),
164*4882a593Smuzhiyun E(EUNATCH),
165*4882a593Smuzhiyun E(EUSERS),
166*4882a593Smuzhiyun E(EXDEV),
167*4882a593Smuzhiyun E(EXFULL),
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun E(ECANCELED), /* ECANCELLED */
170*4882a593Smuzhiyun E(EAGAIN), /* EWOULDBLOCK */
171*4882a593Smuzhiyun E(ECONNREFUSED), /* EREFUSED */
172*4882a593Smuzhiyun E(EDEADLK), /* EDEADLOCK */
173*4882a593Smuzhiyun };
174*4882a593Smuzhiyun #undef E
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun #define E(err) [err - 512 + BUILD_BUG_ON_ZERO(err < 512 || err > 550)] = "-" #err
177*4882a593Smuzhiyun static const char *names_512[] = {
178*4882a593Smuzhiyun E(ERESTARTSYS),
179*4882a593Smuzhiyun E(ERESTARTNOINTR),
180*4882a593Smuzhiyun E(ERESTARTNOHAND),
181*4882a593Smuzhiyun E(ENOIOCTLCMD),
182*4882a593Smuzhiyun E(ERESTART_RESTARTBLOCK),
183*4882a593Smuzhiyun E(EPROBE_DEFER),
184*4882a593Smuzhiyun E(EOPENSTALE),
185*4882a593Smuzhiyun E(ENOPARAM),
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun E(EBADHANDLE),
188*4882a593Smuzhiyun E(ENOTSYNC),
189*4882a593Smuzhiyun E(EBADCOOKIE),
190*4882a593Smuzhiyun E(ENOTSUPP),
191*4882a593Smuzhiyun E(ETOOSMALL),
192*4882a593Smuzhiyun E(ESERVERFAULT),
193*4882a593Smuzhiyun E(EBADTYPE),
194*4882a593Smuzhiyun E(EJUKEBOX),
195*4882a593Smuzhiyun E(EIOCBQUEUED),
196*4882a593Smuzhiyun E(ERECALLCONFLICT),
197*4882a593Smuzhiyun };
198*4882a593Smuzhiyun #undef E
199*4882a593Smuzhiyun
__errname(unsigned err)200*4882a593Smuzhiyun static const char *__errname(unsigned err)
201*4882a593Smuzhiyun {
202*4882a593Smuzhiyun if (err < ARRAY_SIZE(names_0))
203*4882a593Smuzhiyun return names_0[err];
204*4882a593Smuzhiyun if (err >= 512 && err - 512 < ARRAY_SIZE(names_512))
205*4882a593Smuzhiyun return names_512[err - 512];
206*4882a593Smuzhiyun /* But why? */
207*4882a593Smuzhiyun if (IS_ENABLED(CONFIG_MIPS) && err == EDQUOT) /* 1133 */
208*4882a593Smuzhiyun return "-EDQUOT";
209*4882a593Smuzhiyun return NULL;
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun /*
213*4882a593Smuzhiyun * errname(EIO) -> "EIO"
214*4882a593Smuzhiyun * errname(-EIO) -> "-EIO"
215*4882a593Smuzhiyun */
errname(int err)216*4882a593Smuzhiyun const char *errname(int err)
217*4882a593Smuzhiyun {
218*4882a593Smuzhiyun const char *name = __errname(abs(err));
219*4882a593Smuzhiyun if (!name)
220*4882a593Smuzhiyun return NULL;
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun return err > 0 ? name + 1 : name;
223*4882a593Smuzhiyun }
224