strerror.c revision 1.1 1 1.1 christos /* Extended support for using errno values.
2 1.1 christos Written by Fred Fish. fnf (at) cygnus.com
3 1.1 christos This file is in the public domain. --Per Bothner. */
4 1.1 christos
5 1.1 christos #include "config.h"
6 1.1 christos
7 1.1 christos #ifdef HAVE_SYS_ERRLIST
8 1.1 christos /* Note that errno.h (not sure what OS) or stdio.h (BSD 4.4, at least)
9 1.1 christos might declare sys_errlist in a way that the compiler might consider
10 1.1 christos incompatible with our later declaration, perhaps by using const
11 1.1 christos attributes. So we hide the declaration in errno.h (if any) using a
12 1.1 christos macro. */
13 1.1 christos #define sys_nerr sys_nerr__
14 1.1 christos #define sys_errlist sys_errlist__
15 1.1 christos #endif
16 1.1 christos
17 1.1 christos #include "ansidecl.h"
18 1.1 christos #include "libiberty.h"
19 1.1 christos
20 1.1 christos #include <stdio.h>
21 1.1 christos #include <errno.h>
22 1.1 christos
23 1.1 christos #ifdef HAVE_SYS_ERRLIST
24 1.1 christos #undef sys_nerr
25 1.1 christos #undef sys_errlist
26 1.1 christos #endif
27 1.1 christos
28 1.1 christos /* Routines imported from standard C runtime libraries. */
29 1.1 christos
30 1.1 christos #ifdef HAVE_STDLIB_H
31 1.1 christos #include <stdlib.h>
32 1.1 christos #else
33 1.1 christos extern PTR malloc ();
34 1.1 christos #endif
35 1.1 christos
36 1.1 christos #ifdef HAVE_STRING_H
37 1.1 christos #include <string.h>
38 1.1 christos #else
39 1.1 christos extern PTR memset ();
40 1.1 christos #endif
41 1.1 christos
42 1.1 christos #ifndef MAX
43 1.1 christos # define MAX(a,b) ((a) > (b) ? (a) : (b))
44 1.1 christos #endif
45 1.1 christos
46 1.1 christos static void init_error_tables (void);
47 1.1 christos
48 1.1 christos /* Translation table for errno values. See intro(2) in most UNIX systems
49 1.1 christos Programmers Reference Manuals.
50 1.1 christos
51 1.1 christos Note that this table is generally only accessed when it is used at runtime
52 1.1 christos to initialize errno name and message tables that are indexed by errno
53 1.1 christos value.
54 1.1 christos
55 1.1 christos Not all of these errnos will exist on all systems. This table is the only
56 1.1 christos thing that should have to be updated as new error numbers are introduced.
57 1.1 christos It's sort of ugly, but at least its portable. */
58 1.1 christos
59 1.1 christos struct error_info
60 1.1 christos {
61 1.1 christos const int value; /* The numeric value from <errno.h> */
62 1.1 christos const char *const name; /* The equivalent symbolic value */
63 1.1 christos #ifndef HAVE_SYS_ERRLIST
64 1.1 christos const char *const msg; /* Short message about this value */
65 1.1 christos #endif
66 1.1 christos };
67 1.1 christos
68 1.1 christos #ifndef HAVE_SYS_ERRLIST
69 1.1 christos # define ENTRY(value, name, msg) {value, name, msg}
70 1.1 christos #else
71 1.1 christos # define ENTRY(value, name, msg) {value, name}
72 1.1 christos #endif
73 1.1 christos
74 1.1 christos static const struct error_info error_table[] =
75 1.1 christos {
76 1.1 christos #if defined (EPERM)
77 1.1 christos ENTRY(EPERM, "EPERM", "Not owner"),
78 1.1 christos #endif
79 1.1 christos #if defined (ENOENT)
80 1.1 christos ENTRY(ENOENT, "ENOENT", "No such file or directory"),
81 1.1 christos #endif
82 1.1 christos #if defined (ESRCH)
83 1.1 christos ENTRY(ESRCH, "ESRCH", "No such process"),
84 1.1 christos #endif
85 1.1 christos #if defined (EINTR)
86 1.1 christos ENTRY(EINTR, "EINTR", "Interrupted system call"),
87 1.1 christos #endif
88 1.1 christos #if defined (EIO)
89 1.1 christos ENTRY(EIO, "EIO", "I/O error"),
90 1.1 christos #endif
91 1.1 christos #if defined (ENXIO)
92 1.1 christos ENTRY(ENXIO, "ENXIO", "No such device or address"),
93 1.1 christos #endif
94 1.1 christos #if defined (E2BIG)
95 1.1 christos ENTRY(E2BIG, "E2BIG", "Arg list too long"),
96 1.1 christos #endif
97 1.1 christos #if defined (ENOEXEC)
98 1.1 christos ENTRY(ENOEXEC, "ENOEXEC", "Exec format error"),
99 1.1 christos #endif
100 1.1 christos #if defined (EBADF)
101 1.1 christos ENTRY(EBADF, "EBADF", "Bad file number"),
102 1.1 christos #endif
103 1.1 christos #if defined (ECHILD)
104 1.1 christos ENTRY(ECHILD, "ECHILD", "No child processes"),
105 1.1 christos #endif
106 1.1 christos #if defined (EWOULDBLOCK) /* Put before EAGAIN, sometimes aliased */
107 1.1 christos ENTRY(EWOULDBLOCK, "EWOULDBLOCK", "Operation would block"),
108 1.1 christos #endif
109 1.1 christos #if defined (EAGAIN)
110 1.1 christos ENTRY(EAGAIN, "EAGAIN", "No more processes"),
111 1.1 christos #endif
112 1.1 christos #if defined (ENOMEM)
113 1.1 christos ENTRY(ENOMEM, "ENOMEM", "Not enough space"),
114 1.1 christos #endif
115 1.1 christos #if defined (EACCES)
116 1.1 christos ENTRY(EACCES, "EACCES", "Permission denied"),
117 1.1 christos #endif
118 1.1 christos #if defined (EFAULT)
119 1.1 christos ENTRY(EFAULT, "EFAULT", "Bad address"),
120 1.1 christos #endif
121 1.1 christos #if defined (ENOTBLK)
122 1.1 christos ENTRY(ENOTBLK, "ENOTBLK", "Block device required"),
123 1.1 christos #endif
124 1.1 christos #if defined (EBUSY)
125 1.1 christos ENTRY(EBUSY, "EBUSY", "Device busy"),
126 1.1 christos #endif
127 1.1 christos #if defined (EEXIST)
128 1.1 christos ENTRY(EEXIST, "EEXIST", "File exists"),
129 1.1 christos #endif
130 1.1 christos #if defined (EXDEV)
131 1.1 christos ENTRY(EXDEV, "EXDEV", "Cross-device link"),
132 1.1 christos #endif
133 1.1 christos #if defined (ENODEV)
134 1.1 christos ENTRY(ENODEV, "ENODEV", "No such device"),
135 1.1 christos #endif
136 1.1 christos #if defined (ENOTDIR)
137 1.1 christos ENTRY(ENOTDIR, "ENOTDIR", "Not a directory"),
138 1.1 christos #endif
139 1.1 christos #if defined (EISDIR)
140 1.1 christos ENTRY(EISDIR, "EISDIR", "Is a directory"),
141 1.1 christos #endif
142 1.1 christos #if defined (EINVAL)
143 1.1 christos ENTRY(EINVAL, "EINVAL", "Invalid argument"),
144 1.1 christos #endif
145 1.1 christos #if defined (ENFILE)
146 1.1 christos ENTRY(ENFILE, "ENFILE", "File table overflow"),
147 1.1 christos #endif
148 1.1 christos #if defined (EMFILE)
149 1.1 christos ENTRY(EMFILE, "EMFILE", "Too many open files"),
150 1.1 christos #endif
151 1.1 christos #if defined (ENOTTY)
152 1.1 christos ENTRY(ENOTTY, "ENOTTY", "Not a typewriter"),
153 1.1 christos #endif
154 1.1 christos #if defined (ETXTBSY)
155 1.1 christos ENTRY(ETXTBSY, "ETXTBSY", "Text file busy"),
156 1.1 christos #endif
157 1.1 christos #if defined (EFBIG)
158 1.1 christos ENTRY(EFBIG, "EFBIG", "File too large"),
159 1.1 christos #endif
160 1.1 christos #if defined (ENOSPC)
161 1.1 christos ENTRY(ENOSPC, "ENOSPC", "No space left on device"),
162 1.1 christos #endif
163 1.1 christos #if defined (ESPIPE)
164 1.1 christos ENTRY(ESPIPE, "ESPIPE", "Illegal seek"),
165 1.1 christos #endif
166 1.1 christos #if defined (EROFS)
167 1.1 christos ENTRY(EROFS, "EROFS", "Read-only file system"),
168 1.1 christos #endif
169 1.1 christos #if defined (EMLINK)
170 1.1 christos ENTRY(EMLINK, "EMLINK", "Too many links"),
171 1.1 christos #endif
172 1.1 christos #if defined (EPIPE)
173 1.1 christos ENTRY(EPIPE, "EPIPE", "Broken pipe"),
174 1.1 christos #endif
175 1.1 christos #if defined (EDOM)
176 1.1 christos ENTRY(EDOM, "EDOM", "Math argument out of domain of func"),
177 1.1 christos #endif
178 1.1 christos #if defined (ERANGE)
179 1.1 christos ENTRY(ERANGE, "ERANGE", "Math result not representable"),
180 1.1 christos #endif
181 1.1 christos #if defined (ENOMSG)
182 1.1 christos ENTRY(ENOMSG, "ENOMSG", "No message of desired type"),
183 1.1 christos #endif
184 1.1 christos #if defined (EIDRM)
185 1.1 christos ENTRY(EIDRM, "EIDRM", "Identifier removed"),
186 1.1 christos #endif
187 1.1 christos #if defined (ECHRNG)
188 1.1 christos ENTRY(ECHRNG, "ECHRNG", "Channel number out of range"),
189 1.1 christos #endif
190 1.1 christos #if defined (EL2NSYNC)
191 1.1 christos ENTRY(EL2NSYNC, "EL2NSYNC", "Level 2 not synchronized"),
192 1.1 christos #endif
193 1.1 christos #if defined (EL3HLT)
194 1.1 christos ENTRY(EL3HLT, "EL3HLT", "Level 3 halted"),
195 1.1 christos #endif
196 1.1 christos #if defined (EL3RST)
197 1.1 christos ENTRY(EL3RST, "EL3RST", "Level 3 reset"),
198 1.1 christos #endif
199 1.1 christos #if defined (ELNRNG)
200 1.1 christos ENTRY(ELNRNG, "ELNRNG", "Link number out of range"),
201 1.1 christos #endif
202 1.1 christos #if defined (EUNATCH)
203 1.1 christos ENTRY(EUNATCH, "EUNATCH", "Protocol driver not attached"),
204 1.1 christos #endif
205 1.1 christos #if defined (ENOCSI)
206 1.1 christos ENTRY(ENOCSI, "ENOCSI", "No CSI structure available"),
207 1.1 christos #endif
208 1.1 christos #if defined (EL2HLT)
209 1.1 christos ENTRY(EL2HLT, "EL2HLT", "Level 2 halted"),
210 1.1 christos #endif
211 1.1 christos #if defined (EDEADLK)
212 1.1 christos ENTRY(EDEADLK, "EDEADLK", "Deadlock condition"),
213 1.1 christos #endif
214 1.1 christos #if defined (ENOLCK)
215 1.1 christos ENTRY(ENOLCK, "ENOLCK", "No record locks available"),
216 1.1 christos #endif
217 1.1 christos #if defined (EBADE)
218 1.1 christos ENTRY(EBADE, "EBADE", "Invalid exchange"),
219 1.1 christos #endif
220 1.1 christos #if defined (EBADR)
221 1.1 christos ENTRY(EBADR, "EBADR", "Invalid request descriptor"),
222 1.1 christos #endif
223 1.1 christos #if defined (EXFULL)
224 1.1 christos ENTRY(EXFULL, "EXFULL", "Exchange full"),
225 1.1 christos #endif
226 1.1 christos #if defined (ENOANO)
227 1.1 christos ENTRY(ENOANO, "ENOANO", "No anode"),
228 1.1 christos #endif
229 1.1 christos #if defined (EBADRQC)
230 1.1 christos ENTRY(EBADRQC, "EBADRQC", "Invalid request code"),
231 1.1 christos #endif
232 1.1 christos #if defined (EBADSLT)
233 1.1 christos ENTRY(EBADSLT, "EBADSLT", "Invalid slot"),
234 1.1 christos #endif
235 1.1 christos #if defined (EDEADLOCK)
236 1.1 christos ENTRY(EDEADLOCK, "EDEADLOCK", "File locking deadlock error"),
237 1.1 christos #endif
238 1.1 christos #if defined (EBFONT)
239 1.1 christos ENTRY(EBFONT, "EBFONT", "Bad font file format"),
240 1.1 christos #endif
241 1.1 christos #if defined (ENOSTR)
242 1.1 christos ENTRY(ENOSTR, "ENOSTR", "Device not a stream"),
243 1.1 christos #endif
244 1.1 christos #if defined (ENODATA)
245 1.1 christos ENTRY(ENODATA, "ENODATA", "No data available"),
246 1.1 christos #endif
247 1.1 christos #if defined (ETIME)
248 1.1 christos ENTRY(ETIME, "ETIME", "Timer expired"),
249 1.1 christos #endif
250 1.1 christos #if defined (ENOSR)
251 1.1 christos ENTRY(ENOSR, "ENOSR", "Out of streams resources"),
252 1.1 christos #endif
253 1.1 christos #if defined (ENONET)
254 1.1 christos ENTRY(ENONET, "ENONET", "Machine is not on the network"),
255 1.1 christos #endif
256 1.1 christos #if defined (ENOPKG)
257 1.1 christos ENTRY(ENOPKG, "ENOPKG", "Package not installed"),
258 1.1 christos #endif
259 1.1 christos #if defined (EREMOTE)
260 1.1 christos ENTRY(EREMOTE, "EREMOTE", "Object is remote"),
261 1.1 christos #endif
262 1.1 christos #if defined (ENOLINK)
263 1.1 christos ENTRY(ENOLINK, "ENOLINK", "Link has been severed"),
264 1.1 christos #endif
265 1.1 christos #if defined (EADV)
266 1.1 christos ENTRY(EADV, "EADV", "Advertise error"),
267 1.1 christos #endif
268 1.1 christos #if defined (ESRMNT)
269 1.1 christos ENTRY(ESRMNT, "ESRMNT", "Srmount error"),
270 1.1 christos #endif
271 1.1 christos #if defined (ECOMM)
272 1.1 christos ENTRY(ECOMM, "ECOMM", "Communication error on send"),
273 1.1 christos #endif
274 1.1 christos #if defined (EPROTO)
275 1.1 christos ENTRY(EPROTO, "EPROTO", "Protocol error"),
276 1.1 christos #endif
277 1.1 christos #if defined (EMULTIHOP)
278 1.1 christos ENTRY(EMULTIHOP, "EMULTIHOP", "Multihop attempted"),
279 1.1 christos #endif
280 1.1 christos #if defined (EDOTDOT)
281 1.1 christos ENTRY(EDOTDOT, "EDOTDOT", "RFS specific error"),
282 1.1 christos #endif
283 1.1 christos #if defined (EBADMSG)
284 1.1 christos ENTRY(EBADMSG, "EBADMSG", "Not a data message"),
285 1.1 christos #endif
286 1.1 christos #if defined (ENAMETOOLONG)
287 1.1 christos ENTRY(ENAMETOOLONG, "ENAMETOOLONG", "File name too long"),
288 1.1 christos #endif
289 1.1 christos #if defined (EOVERFLOW)
290 1.1 christos ENTRY(EOVERFLOW, "EOVERFLOW", "Value too large for defined data type"),
291 1.1 christos #endif
292 1.1 christos #if defined (ENOTUNIQ)
293 1.1 christos ENTRY(ENOTUNIQ, "ENOTUNIQ", "Name not unique on network"),
294 1.1 christos #endif
295 1.1 christos #if defined (EBADFD)
296 1.1 christos ENTRY(EBADFD, "EBADFD", "File descriptor in bad state"),
297 1.1 christos #endif
298 1.1 christos #if defined (EREMCHG)
299 1.1 christos ENTRY(EREMCHG, "EREMCHG", "Remote address changed"),
300 1.1 christos #endif
301 1.1 christos #if defined (ELIBACC)
302 1.1 christos ENTRY(ELIBACC, "ELIBACC", "Can not access a needed shared library"),
303 1.1 christos #endif
304 1.1 christos #if defined (ELIBBAD)
305 1.1 christos ENTRY(ELIBBAD, "ELIBBAD", "Accessing a corrupted shared library"),
306 1.1 christos #endif
307 1.1 christos #if defined (ELIBSCN)
308 1.1 christos ENTRY(ELIBSCN, "ELIBSCN", ".lib section in a.out corrupted"),
309 1.1 christos #endif
310 1.1 christos #if defined (ELIBMAX)
311 1.1 christos ENTRY(ELIBMAX, "ELIBMAX", "Attempting to link in too many shared libraries"),
312 1.1 christos #endif
313 1.1 christos #if defined (ELIBEXEC)
314 1.1 christos ENTRY(ELIBEXEC, "ELIBEXEC", "Cannot exec a shared library directly"),
315 1.1 christos #endif
316 1.1 christos #if defined (EILSEQ)
317 1.1 christos ENTRY(EILSEQ, "EILSEQ", "Illegal byte sequence"),
318 1.1 christos #endif
319 1.1 christos #if defined (ENOSYS)
320 1.1 christos ENTRY(ENOSYS, "ENOSYS", "Operation not applicable"),
321 1.1 christos #endif
322 1.1 christos #if defined (ELOOP)
323 1.1 christos ENTRY(ELOOP, "ELOOP", "Too many symbolic links encountered"),
324 1.1 christos #endif
325 1.1 christos #if defined (ERESTART)
326 1.1 christos ENTRY(ERESTART, "ERESTART", "Interrupted system call should be restarted"),
327 1.1 christos #endif
328 1.1 christos #if defined (ESTRPIPE)
329 1.1 christos ENTRY(ESTRPIPE, "ESTRPIPE", "Streams pipe error"),
330 1.1 christos #endif
331 1.1 christos #if defined (ENOTEMPTY)
332 1.1 christos ENTRY(ENOTEMPTY, "ENOTEMPTY", "Directory not empty"),
333 1.1 christos #endif
334 1.1 christos #if defined (EUSERS)
335 1.1 christos ENTRY(EUSERS, "EUSERS", "Too many users"),
336 1.1 christos #endif
337 1.1 christos #if defined (ENOTSOCK)
338 1.1 christos ENTRY(ENOTSOCK, "ENOTSOCK", "Socket operation on non-socket"),
339 1.1 christos #endif
340 1.1 christos #if defined (EDESTADDRREQ)
341 1.1 christos ENTRY(EDESTADDRREQ, "EDESTADDRREQ", "Destination address required"),
342 1.1 christos #endif
343 1.1 christos #if defined (EMSGSIZE)
344 1.1 christos ENTRY(EMSGSIZE, "EMSGSIZE", "Message too long"),
345 1.1 christos #endif
346 1.1 christos #if defined (EPROTOTYPE)
347 1.1 christos ENTRY(EPROTOTYPE, "EPROTOTYPE", "Protocol wrong type for socket"),
348 1.1 christos #endif
349 1.1 christos #if defined (ENOPROTOOPT)
350 1.1 christos ENTRY(ENOPROTOOPT, "ENOPROTOOPT", "Protocol option not available"),
351 1.1 christos #endif
352 1.1 christos #if defined (EPROTONOSUPPORT)
353 1.1 christos ENTRY(EPROTONOSUPPORT, "EPROTONOSUPPORT", "Protocol not supported"),
354 1.1 christos #endif
355 1.1 christos #if defined (ESOCKTNOSUPPORT)
356 1.1 christos ENTRY(ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT", "Socket type not supported"),
357 1.1 christos #endif
358 1.1 christos #if defined (EOPNOTSUPP)
359 1.1 christos ENTRY(EOPNOTSUPP, "EOPNOTSUPP", "Operation not supported on transport endpoint"),
360 1.1 christos #endif
361 1.1 christos #if defined (EPFNOSUPPORT)
362 1.1 christos ENTRY(EPFNOSUPPORT, "EPFNOSUPPORT", "Protocol family not supported"),
363 1.1 christos #endif
364 1.1 christos #if defined (EAFNOSUPPORT)
365 1.1 christos ENTRY(EAFNOSUPPORT, "EAFNOSUPPORT", "Address family not supported by protocol"),
366 1.1 christos #endif
367 1.1 christos #if defined (EADDRINUSE)
368 1.1 christos ENTRY(EADDRINUSE, "EADDRINUSE", "Address already in use"),
369 1.1 christos #endif
370 1.1 christos #if defined (EADDRNOTAVAIL)
371 1.1 christos ENTRY(EADDRNOTAVAIL, "EADDRNOTAVAIL","Cannot assign requested address"),
372 1.1 christos #endif
373 1.1 christos #if defined (ENETDOWN)
374 1.1 christos ENTRY(ENETDOWN, "ENETDOWN", "Network is down"),
375 1.1 christos #endif
376 1.1 christos #if defined (ENETUNREACH)
377 1.1 christos ENTRY(ENETUNREACH, "ENETUNREACH", "Network is unreachable"),
378 1.1 christos #endif
379 1.1 christos #if defined (ENETRESET)
380 1.1 christos ENTRY(ENETRESET, "ENETRESET", "Network dropped connection because of reset"),
381 1.1 christos #endif
382 1.1 christos #if defined (ECONNABORTED)
383 1.1 christos ENTRY(ECONNABORTED, "ECONNABORTED", "Software caused connection abort"),
384 1.1 christos #endif
385 1.1 christos #if defined (ECONNRESET)
386 1.1 christos ENTRY(ECONNRESET, "ECONNRESET", "Connection reset by peer"),
387 1.1 christos #endif
388 1.1 christos #if defined (ENOBUFS)
389 1.1 christos ENTRY(ENOBUFS, "ENOBUFS", "No buffer space available"),
390 1.1 christos #endif
391 1.1 christos #if defined (EISCONN)
392 1.1 christos ENTRY(EISCONN, "EISCONN", "Transport endpoint is already connected"),
393 1.1 christos #endif
394 1.1 christos #if defined (ENOTCONN)
395 1.1 christos ENTRY(ENOTCONN, "ENOTCONN", "Transport endpoint is not connected"),
396 1.1 christos #endif
397 1.1 christos #if defined (ESHUTDOWN)
398 1.1 christos ENTRY(ESHUTDOWN, "ESHUTDOWN", "Cannot send after transport endpoint shutdown"),
399 1.1 christos #endif
400 1.1 christos #if defined (ETOOMANYREFS)
401 1.1 christos ENTRY(ETOOMANYREFS, "ETOOMANYREFS", "Too many references: cannot splice"),
402 1.1 christos #endif
403 1.1 christos #if defined (ETIMEDOUT)
404 1.1 christos ENTRY(ETIMEDOUT, "ETIMEDOUT", "Connection timed out"),
405 1.1 christos #endif
406 1.1 christos #if defined (ECONNREFUSED)
407 1.1 christos ENTRY(ECONNREFUSED, "ECONNREFUSED", "Connection refused"),
408 1.1 christos #endif
409 1.1 christos #if defined (EHOSTDOWN)
410 1.1 christos ENTRY(EHOSTDOWN, "EHOSTDOWN", "Host is down"),
411 1.1 christos #endif
412 1.1 christos #if defined (EHOSTUNREACH)
413 1.1 christos ENTRY(EHOSTUNREACH, "EHOSTUNREACH", "No route to host"),
414 1.1 christos #endif
415 1.1 christos #if defined (EALREADY)
416 1.1 christos ENTRY(EALREADY, "EALREADY", "Operation already in progress"),
417 1.1 christos #endif
418 1.1 christos #if defined (EINPROGRESS)
419 1.1 christos ENTRY(EINPROGRESS, "EINPROGRESS", "Operation now in progress"),
420 1.1 christos #endif
421 1.1 christos #if defined (ESTALE)
422 1.1 christos ENTRY(ESTALE, "ESTALE", "Stale NFS file handle"),
423 1.1 christos #endif
424 1.1 christos #if defined (EUCLEAN)
425 1.1 christos ENTRY(EUCLEAN, "EUCLEAN", "Structure needs cleaning"),
426 1.1 christos #endif
427 1.1 christos #if defined (ENOTNAM)
428 1.1 christos ENTRY(ENOTNAM, "ENOTNAM", "Not a XENIX named type file"),
429 1.1 christos #endif
430 1.1 christos #if defined (ENAVAIL)
431 1.1 christos ENTRY(ENAVAIL, "ENAVAIL", "No XENIX semaphores available"),
432 1.1 christos #endif
433 1.1 christos #if defined (EISNAM)
434 1.1 christos ENTRY(EISNAM, "EISNAM", "Is a named type file"),
435 1.1 christos #endif
436 1.1 christos #if defined (EREMOTEIO)
437 1.1 christos ENTRY(EREMOTEIO, "EREMOTEIO", "Remote I/O error"),
438 1.1 christos #endif
439 1.1 christos ENTRY(0, NULL, NULL)
440 1.1 christos };
441 1.1 christos
442 1.1 christos #ifdef EVMSERR
443 1.1 christos /* This is not in the table, because the numeric value of EVMSERR (32767)
444 1.1 christos lies outside the range of sys_errlist[]. */
445 1.1 christos static struct { int value; const char *name, *msg; }
446 1.1 christos evmserr = { EVMSERR, "EVMSERR", "VMS-specific error" };
447 1.1 christos #endif
448 1.1 christos
449 1.1 christos /* Translation table allocated and initialized at runtime. Indexed by the
450 1.1 christos errno value to find the equivalent symbolic value. */
451 1.1 christos
452 1.1 christos static const char **error_names;
453 1.1 christos static int num_error_names = 0;
454 1.1 christos
455 1.1 christos /* Translation table allocated and initialized at runtime, if it does not
456 1.1 christos already exist in the host environment. Indexed by the errno value to find
457 1.1 christos the descriptive string.
458 1.1 christos
459 1.1 christos We don't export it for use in other modules because even though it has the
460 1.1 christos same name, it differs from other implementations in that it is dynamically
461 1.1 christos initialized rather than statically initialized. */
462 1.1 christos
463 1.1 christos #ifndef HAVE_SYS_ERRLIST
464 1.1 christos
465 1.1 christos #define sys_nerr sys_nerr__
466 1.1 christos #define sys_errlist sys_errlist__
467 1.1 christos static int sys_nerr;
468 1.1 christos static const char **sys_errlist;
469 1.1 christos
470 1.1 christos #else
471 1.1 christos
472 1.1 christos extern int sys_nerr;
473 1.1 christos extern char *sys_errlist[];
474 1.1 christos
475 1.1 christos #endif
476 1.1 christos
477 1.1 christos /*
478 1.1 christos
479 1.1 christos NAME
480 1.1 christos
481 1.1 christos init_error_tables -- initialize the name and message tables
482 1.1 christos
483 1.1 christos SYNOPSIS
484 1.1 christos
485 1.1 christos static void init_error_tables ();
486 1.1 christos
487 1.1 christos DESCRIPTION
488 1.1 christos
489 1.1 christos Using the error_table, which is initialized at compile time, generate
490 1.1 christos the error_names and the sys_errlist (if needed) tables, which are
491 1.1 christos indexed at runtime by a specific errno value.
492 1.1 christos
493 1.1 christos BUGS
494 1.1 christos
495 1.1 christos The initialization of the tables may fail under low memory conditions,
496 1.1 christos in which case we don't do anything particularly useful, but we don't
497 1.1 christos bomb either. Who knows, it might succeed at a later point if we free
498 1.1 christos some memory in the meantime. In any case, the other routines know
499 1.1 christos how to deal with lack of a table after trying to initialize it. This
500 1.1 christos may or may not be considered to be a bug, that we don't specifically
501 1.1 christos warn about this particular failure mode.
502 1.1 christos
503 1.1 christos */
504 1.1 christos
505 1.1 christos static void
506 1.1 christos init_error_tables (void)
507 1.1 christos {
508 1.1 christos const struct error_info *eip;
509 1.1 christos int nbytes;
510 1.1 christos
511 1.1 christos /* If we haven't already scanned the error_table once to find the maximum
512 1.1 christos errno value, then go find it now. */
513 1.1 christos
514 1.1 christos if (num_error_names == 0)
515 1.1 christos {
516 1.1 christos for (eip = error_table; eip -> name != NULL; eip++)
517 1.1 christos {
518 1.1 christos if (eip -> value >= num_error_names)
519 1.1 christos {
520 1.1 christos num_error_names = eip -> value + 1;
521 1.1 christos }
522 1.1 christos }
523 1.1 christos }
524 1.1 christos
525 1.1 christos /* Now attempt to allocate the error_names table, zero it out, and then
526 1.1 christos initialize it from the statically initialized error_table. */
527 1.1 christos
528 1.1 christos if (error_names == NULL)
529 1.1 christos {
530 1.1 christos nbytes = num_error_names * sizeof (char *);
531 1.1 christos if ((error_names = (const char **) malloc (nbytes)) != NULL)
532 1.1 christos {
533 1.1 christos memset (error_names, 0, nbytes);
534 1.1 christos for (eip = error_table; eip -> name != NULL; eip++)
535 1.1 christos {
536 1.1 christos error_names[eip -> value] = eip -> name;
537 1.1 christos }
538 1.1 christos }
539 1.1 christos }
540 1.1 christos
541 1.1 christos #ifndef HAVE_SYS_ERRLIST
542 1.1 christos
543 1.1 christos /* Now attempt to allocate the sys_errlist table, zero it out, and then
544 1.1 christos initialize it from the statically initialized error_table. */
545 1.1 christos
546 1.1 christos if (sys_errlist == NULL)
547 1.1 christos {
548 1.1 christos nbytes = num_error_names * sizeof (char *);
549 1.1 christos if ((sys_errlist = (const char **) malloc (nbytes)) != NULL)
550 1.1 christos {
551 1.1 christos memset (sys_errlist, 0, nbytes);
552 1.1 christos sys_nerr = num_error_names;
553 1.1 christos for (eip = error_table; eip -> name != NULL; eip++)
554 1.1 christos {
555 1.1 christos sys_errlist[eip -> value] = eip -> msg;
556 1.1 christos }
557 1.1 christos }
558 1.1 christos }
559 1.1 christos
560 1.1 christos #endif
561 1.1 christos
562 1.1 christos }
563 1.1 christos
564 1.1 christos /*
565 1.1 christos
566 1.1 christos
567 1.1 christos @deftypefn Extension int errno_max (void)
568 1.1 christos
569 1.1 christos Returns the maximum @code{errno} value for which a corresponding
570 1.1 christos symbolic name or message is available. Note that in the case where we
571 1.1 christos use the @code{sys_errlist} supplied by the system, it is possible for
572 1.1 christos there to be more symbolic names than messages, or vice versa. In
573 1.1 christos fact, the manual page for @code{perror(3C)} explicitly warns that one
574 1.1 christos should check the size of the table (@code{sys_nerr}) before indexing
575 1.1 christos it, since new error codes may be added to the system before they are
576 1.1 christos added to the table. Thus @code{sys_nerr} might be smaller than value
577 1.1 christos implied by the largest @code{errno} value defined in @code{<errno.h>}.
578 1.1 christos
579 1.1 christos We return the maximum value that can be used to obtain a meaningful
580 1.1 christos symbolic name or message.
581 1.1 christos
582 1.1 christos @end deftypefn
583 1.1 christos
584 1.1 christos */
585 1.1 christos
586 1.1 christos int
587 1.1 christos errno_max (void)
588 1.1 christos {
589 1.1 christos int maxsize;
590 1.1 christos
591 1.1 christos if (error_names == NULL)
592 1.1 christos {
593 1.1 christos init_error_tables ();
594 1.1 christos }
595 1.1 christos maxsize = MAX (sys_nerr, num_error_names);
596 1.1 christos return (maxsize - 1);
597 1.1 christos }
598 1.1 christos
599 1.1 christos #ifndef HAVE_STRERROR
600 1.1 christos
601 1.1 christos /*
602 1.1 christos
603 1.1 christos @deftypefn Supplemental char* strerror (int @var{errnoval})
604 1.1 christos
605 1.1 christos Maps an @code{errno} number to an error message string, the contents
606 1.1 christos of which are implementation defined. On systems which have the
607 1.1 christos external variables @code{sys_nerr} and @code{sys_errlist}, these
608 1.1 christos strings will be the same as the ones used by @code{perror}.
609 1.1 christos
610 1.1 christos If the supplied error number is within the valid range of indices for
611 1.1 christos the @code{sys_errlist}, but no message is available for the particular
612 1.1 christos error number, then returns the string @samp{Error @var{num}}, where
613 1.1 christos @var{num} is the error number.
614 1.1 christos
615 1.1 christos If the supplied error number is not a valid index into
616 1.1 christos @code{sys_errlist}, returns @code{NULL}.
617 1.1 christos
618 1.1 christos The returned string is only guaranteed to be valid only until the
619 1.1 christos next call to @code{strerror}.
620 1.1 christos
621 1.1 christos @end deftypefn
622 1.1 christos
623 1.1 christos */
624 1.1 christos
625 1.1 christos char *
626 1.1 christos strerror (int errnoval)
627 1.1 christos {
628 1.1 christos const char *msg;
629 1.1 christos static char buf[32];
630 1.1 christos
631 1.1 christos #ifndef HAVE_SYS_ERRLIST
632 1.1 christos
633 1.1 christos if (error_names == NULL)
634 1.1 christos {
635 1.1 christos init_error_tables ();
636 1.1 christos }
637 1.1 christos
638 1.1 christos #endif
639 1.1 christos
640 1.1 christos if ((errnoval < 0) || (errnoval >= sys_nerr))
641 1.1 christos {
642 1.1 christos #ifdef EVMSERR
643 1.1 christos if (errnoval == evmserr.value)
644 1.1 christos msg = evmserr.msg;
645 1.1 christos else
646 1.1 christos #endif
647 1.1 christos /* Out of range, just return NULL */
648 1.1 christos msg = NULL;
649 1.1 christos }
650 1.1 christos else if ((sys_errlist == NULL) || (sys_errlist[errnoval] == NULL))
651 1.1 christos {
652 1.1 christos /* In range, but no sys_errlist or no entry at this index. */
653 1.1 christos sprintf (buf, "Error %d", errnoval);
654 1.1 christos msg = buf;
655 1.1 christos }
656 1.1 christos else
657 1.1 christos {
658 1.1 christos /* In range, and a valid message. Just return the message. */
659 1.1 christos msg = (char *) sys_errlist[errnoval];
660 1.1 christos }
661 1.1 christos
662 1.1 christos return (msg);
663 1.1 christos }
664 1.1 christos
665 1.1 christos #endif /* ! HAVE_STRERROR */
666 1.1 christos
667 1.1 christos
668 1.1 christos /*
669 1.1 christos
670 1.1 christos @deftypefn Replacement {const char*} strerrno (int @var{errnum})
671 1.1 christos
672 1.1 christos Given an error number returned from a system call (typically returned
673 1.1 christos in @code{errno}), returns a pointer to a string containing the
674 1.1 christos symbolic name of that error number, as found in @code{<errno.h>}.
675 1.1 christos
676 1.1 christos If the supplied error number is within the valid range of indices for
677 1.1 christos symbolic names, but no name is available for the particular error
678 1.1 christos number, then returns the string @samp{Error @var{num}}, where @var{num}
679 1.1 christos is the error number.
680 1.1 christos
681 1.1 christos If the supplied error number is not within the range of valid
682 1.1 christos indices, then returns @code{NULL}.
683 1.1 christos
684 1.1 christos The contents of the location pointed to are only guaranteed to be
685 1.1 christos valid until the next call to @code{strerrno}.
686 1.1 christos
687 1.1 christos @end deftypefn
688 1.1 christos
689 1.1 christos */
690 1.1 christos
691 1.1 christos const char *
692 1.1 christos strerrno (int errnoval)
693 1.1 christos {
694 1.1 christos const char *name;
695 1.1 christos static char buf[32];
696 1.1 christos
697 1.1 christos if (error_names == NULL)
698 1.1 christos {
699 1.1 christos init_error_tables ();
700 1.1 christos }
701 1.1 christos
702 1.1 christos if ((errnoval < 0) || (errnoval >= num_error_names))
703 1.1 christos {
704 1.1 christos #ifdef EVMSERR
705 1.1 christos if (errnoval == evmserr.value)
706 1.1 christos name = evmserr.name;
707 1.1 christos else
708 1.1 christos #endif
709 1.1 christos /* Out of range, just return NULL */
710 1.1 christos name = NULL;
711 1.1 christos }
712 1.1 christos else if ((error_names == NULL) || (error_names[errnoval] == NULL))
713 1.1 christos {
714 1.1 christos /* In range, but no error_names or no entry at this index. */
715 1.1 christos sprintf (buf, "Error %d", errnoval);
716 1.1 christos name = (const char *) buf;
717 1.1 christos }
718 1.1 christos else
719 1.1 christos {
720 1.1 christos /* In range, and a valid name. Just return the name. */
721 1.1 christos name = error_names[errnoval];
722 1.1 christos }
723 1.1 christos
724 1.1 christos return (name);
725 1.1 christos }
726 1.1 christos
727 1.1 christos /*
728 1.1 christos
729 1.1 christos @deftypefn Extension int strtoerrno (const char *@var{name})
730 1.1 christos
731 1.1 christos Given the symbolic name of a error number (e.g., @code{EACCES}), map it
732 1.1 christos to an errno value. If no translation is found, returns 0.
733 1.1 christos
734 1.1 christos @end deftypefn
735 1.1 christos
736 1.1 christos */
737 1.1 christos
738 1.1 christos int
739 1.1 christos strtoerrno (const char *name)
740 1.1 christos {
741 1.1 christos int errnoval = 0;
742 1.1 christos
743 1.1 christos if (name != NULL)
744 1.1 christos {
745 1.1 christos if (error_names == NULL)
746 1.1 christos {
747 1.1 christos init_error_tables ();
748 1.1 christos }
749 1.1 christos for (errnoval = 0; errnoval < num_error_names; errnoval++)
750 1.1 christos {
751 1.1 christos if ((error_names[errnoval] != NULL) &&
752 1.1 christos (strcmp (name, error_names[errnoval]) == 0))
753 1.1 christos {
754 1.1 christos break;
755 1.1 christos }
756 1.1 christos }
757 1.1 christos if (errnoval == num_error_names)
758 1.1 christos {
759 1.1 christos #ifdef EVMSERR
760 1.1 christos if (strcmp (name, evmserr.name) == 0)
761 1.1 christos errnoval = evmserr.value;
762 1.1 christos else
763 1.1 christos #endif
764 1.1 christos errnoval = 0;
765 1.1 christos }
766 1.1 christos }
767 1.1 christos return (errnoval);
768 1.1 christos }
769 1.1 christos
770 1.1 christos
771 1.1 christos /* A simple little main that does nothing but print all the errno translations
772 1.1 christos if MAIN is defined and this file is compiled and linked. */
773 1.1 christos
774 1.1 christos #ifdef MAIN
775 1.1 christos
776 1.1 christos #include <stdio.h>
777 1.1 christos
778 1.1 christos int
779 1.1 christos main (void)
780 1.1 christos {
781 1.1 christos int errn;
782 1.1 christos int errnmax;
783 1.1 christos const char *name;
784 1.1 christos const char *msg;
785 1.1 christos char *strerror ();
786 1.1 christos
787 1.1 christos errnmax = errno_max ();
788 1.1 christos printf ("%d entries in names table.\n", num_error_names);
789 1.1 christos printf ("%d entries in messages table.\n", sys_nerr);
790 1.1 christos printf ("%d is max useful index.\n", errnmax);
791 1.1 christos
792 1.1 christos /* Keep printing values until we get to the end of *both* tables, not
793 1.1 christos *either* table. Note that knowing the maximum useful index does *not*
794 1.1 christos relieve us of the responsibility of testing the return pointer for
795 1.1 christos NULL. */
796 1.1 christos
797 1.1 christos for (errn = 0; errn <= errnmax; errn++)
798 1.1 christos {
799 1.1 christos name = strerrno (errn);
800 1.1 christos name = (name == NULL) ? "<NULL>" : name;
801 1.1 christos msg = strerror (errn);
802 1.1 christos msg = (msg == NULL) ? "<NULL>" : msg;
803 1.1 christos printf ("%-4d%-18s%s\n", errn, name, msg);
804 1.1 christos }
805 1.1 christos
806 1.1 christos return 0;
807 1.1 christos }
808 1.1 christos
809 1.1 christos #endif
810