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