1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /*
3 * This file essentially replicates NSPR's source for the functions that
4 * map system-specific error codes to NSPR error codes. We would use
5 * NSPR's functions, instead of duplicating them, but they're private.
6 * As long as SSL's server session cache code must do platform native I/O
7 * to accomplish its job, and NSPR's error mapping functions remain private,
8 * this code will continue to need to be replicated.
9 *
10 * This Source Code Form is subject to the terms of the Mozilla Public
11 * License, v. 2.0. If a copy of the MPL was not distributed with this
12 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
13
14 #if 0
15 #include "primpl.h"
16 #else
17 #define _PR_POLL_AVAILABLE 1
18 #include "prerror.h"
19 #endif
20
21 #if defined (__bsdi__) || defined(NTO) || defined(DARWIN) || defined(BEOS)
22 #undef _PR_POLL_AVAILABLE
23 #endif
24
25 #if defined(_PR_POLL_AVAILABLE)
26 #include <poll.h>
27 #endif
28 #include <errno.h>
29
30 /* forward declarations. */
31 void nss_MD_unix_map_default_error(int err);
32
nss_MD_unix_map_opendir_error(int err)33 void nss_MD_unix_map_opendir_error(int err)
34 {
35 nss_MD_unix_map_default_error(err);
36 }
37
nss_MD_unix_map_closedir_error(int err)38 void nss_MD_unix_map_closedir_error(int err)
39 {
40 PRErrorCode prError;
41 switch (err) {
42 case EINVAL: prError = PR_BAD_DESCRIPTOR_ERROR; break;
43 default: nss_MD_unix_map_default_error(err); return;
44 }
45 PR_SetError(prError, err);
46 }
47
nss_MD_unix_readdir_error(int err)48 void nss_MD_unix_readdir_error(int err)
49 {
50 PRErrorCode prError;
51
52 switch (err) {
53 case ENOENT: prError = PR_NO_MORE_FILES_ERROR; break;
54 #ifdef EOVERFLOW
55 case EOVERFLOW: prError = PR_IO_ERROR; break;
56 #endif
57 case EINVAL: prError = PR_IO_ERROR; break;
58 case ENXIO: prError = PR_IO_ERROR; break;
59 default: nss_MD_unix_map_default_error(err); return;
60 }
61 PR_SetError(prError, err);
62 }
63
nss_MD_unix_map_unlink_error(int err)64 void nss_MD_unix_map_unlink_error(int err)
65 {
66 PRErrorCode prError;
67 switch (err) {
68 case EPERM: prError = PR_IS_DIRECTORY_ERROR; break;
69 default: nss_MD_unix_map_default_error(err); return;
70 }
71 PR_SetError(prError, err);
72 }
73
nss_MD_unix_map_stat_error(int err)74 void nss_MD_unix_map_stat_error(int err)
75 {
76 PRErrorCode prError;
77 switch (err) {
78 case ETIMEDOUT: prError = PR_REMOTE_FILE_ERROR; break;
79 default: nss_MD_unix_map_default_error(err); return;
80 }
81 PR_SetError(prError, err);
82 }
83
nss_MD_unix_map_fstat_error(int err)84 void nss_MD_unix_map_fstat_error(int err)
85 {
86 PRErrorCode prError;
87 switch (err) {
88 case ETIMEDOUT: prError = PR_REMOTE_FILE_ERROR; break;
89 default: nss_MD_unix_map_default_error(err); return;
90 }
91 PR_SetError(prError, err);
92 }
93
nss_MD_unix_map_rename_error(int err)94 void nss_MD_unix_map_rename_error(int err)
95 {
96 PRErrorCode prError;
97 switch (err) {
98 case EEXIST: prError = PR_DIRECTORY_NOT_EMPTY_ERROR; break;
99 default: nss_MD_unix_map_default_error(err); return;
100 }
101 PR_SetError(prError, err);
102 }
103
nss_MD_unix_map_access_error(int err)104 void nss_MD_unix_map_access_error(int err)
105 {
106 PRErrorCode prError;
107 switch (err) {
108 case ETIMEDOUT: prError = PR_REMOTE_FILE_ERROR; break;
109 default: nss_MD_unix_map_default_error(err); return;
110 }
111 PR_SetError(prError, err);
112 }
113
nss_MD_unix_map_mkdir_error(int err)114 void nss_MD_unix_map_mkdir_error(int err)
115 {
116 nss_MD_unix_map_default_error(err);
117 }
118
nss_MD_unix_map_rmdir_error(int err)119 void nss_MD_unix_map_rmdir_error(int err)
120 {
121 PRErrorCode prError;
122
123 switch (err) {
124 case EEXIST: prError = PR_DIRECTORY_NOT_EMPTY_ERROR; break;
125 case EINVAL: prError = PR_DIRECTORY_NOT_EMPTY_ERROR; break;
126 case ETIMEDOUT: prError = PR_REMOTE_FILE_ERROR; break;
127 default: nss_MD_unix_map_default_error(err); return;
128 }
129 PR_SetError(prError, err);
130 }
131
nss_MD_unix_map_read_error(int err)132 void nss_MD_unix_map_read_error(int err)
133 {
134 PRErrorCode prError;
135 switch (err) {
136 case EINVAL: prError = PR_INVALID_METHOD_ERROR; break;
137 case ENXIO: prError = PR_INVALID_ARGUMENT_ERROR; break;
138 default: nss_MD_unix_map_default_error(err); return;
139 }
140 PR_SetError(prError, err);
141 }
142
nss_MD_unix_map_write_error(int err)143 void nss_MD_unix_map_write_error(int err)
144 {
145 PRErrorCode prError;
146 switch (err) {
147 case EINVAL: prError = PR_INVALID_METHOD_ERROR; break;
148 case ENXIO: prError = PR_INVALID_METHOD_ERROR; break;
149 case ETIMEDOUT: prError = PR_REMOTE_FILE_ERROR; break;
150 default: nss_MD_unix_map_default_error(err); return;
151 }
152 PR_SetError(prError, err);
153 }
154
nss_MD_unix_map_lseek_error(int err)155 void nss_MD_unix_map_lseek_error(int err)
156 {
157 nss_MD_unix_map_default_error(err);
158 }
159
nss_MD_unix_map_fsync_error(int err)160 void nss_MD_unix_map_fsync_error(int err)
161 {
162 PRErrorCode prError;
163 switch (err) {
164 case ETIMEDOUT: prError = PR_REMOTE_FILE_ERROR; break;
165 case EINVAL: prError = PR_INVALID_METHOD_ERROR; break;
166 default: nss_MD_unix_map_default_error(err); return;
167 }
168 PR_SetError(prError, err);
169 }
170
nss_MD_unix_map_close_error(int err)171 void nss_MD_unix_map_close_error(int err)
172 {
173 PRErrorCode prError;
174 switch (err) {
175 case ETIMEDOUT: prError = PR_REMOTE_FILE_ERROR; break;
176 default: nss_MD_unix_map_default_error(err); return;
177 }
178 PR_SetError(prError, err);
179 }
180
nss_MD_unix_map_socket_error(int err)181 void nss_MD_unix_map_socket_error(int err)
182 {
183 PRErrorCode prError;
184 switch (err) {
185 case ENOMEM: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
186 default: nss_MD_unix_map_default_error(err); return;
187 }
188 PR_SetError(prError, err);
189 }
190
nss_MD_unix_map_socketavailable_error(int err)191 void nss_MD_unix_map_socketavailable_error(int err)
192 {
193 PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
194 }
195
nss_MD_unix_map_recv_error(int err)196 void nss_MD_unix_map_recv_error(int err)
197 {
198 nss_MD_unix_map_default_error(err);
199 }
200
nss_MD_unix_map_recvfrom_error(int err)201 void nss_MD_unix_map_recvfrom_error(int err)
202 {
203 nss_MD_unix_map_default_error(err);
204 }
205
nss_MD_unix_map_send_error(int err)206 void nss_MD_unix_map_send_error(int err)
207 {
208 nss_MD_unix_map_default_error(err);
209 }
210
nss_MD_unix_map_sendto_error(int err)211 void nss_MD_unix_map_sendto_error(int err)
212 {
213 nss_MD_unix_map_default_error(err);
214 }
215
nss_MD_unix_map_writev_error(int err)216 void nss_MD_unix_map_writev_error(int err)
217 {
218 nss_MD_unix_map_default_error(err);
219 }
220
nss_MD_unix_map_accept_error(int err)221 void nss_MD_unix_map_accept_error(int err)
222 {
223 PRErrorCode prError;
224 switch (err) {
225 case ENODEV: prError = PR_NOT_TCP_SOCKET_ERROR; break;
226 default: nss_MD_unix_map_default_error(err); return;
227 }
228 PR_SetError(prError, err);
229 }
230
nss_MD_unix_map_connect_error(int err)231 void nss_MD_unix_map_connect_error(int err)
232 {
233 PRErrorCode prError;
234 switch (err) {
235 case EACCES: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
236 #if defined(UNIXWARE) || defined(SNI) || defined(NEC)
237 /*
238 * On some platforms, if we connect to a port on the local host
239 * (the loopback address) that no process is listening on, we get
240 * EIO instead of ECONNREFUSED.
241 */
242 case EIO: prError = PR_CONNECT_REFUSED_ERROR; break;
243 #endif
244 case ELOOP: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
245 case ENOENT: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
246 case ENXIO: prError = PR_IO_ERROR; break;
247 default: nss_MD_unix_map_default_error(err); return;
248 }
249 PR_SetError(prError, err);
250 }
251
nss_MD_unix_map_bind_error(int err)252 void nss_MD_unix_map_bind_error(int err)
253 {
254 PRErrorCode prError;
255 switch (err) {
256 case EINVAL: prError = PR_SOCKET_ADDRESS_IS_BOUND_ERROR; break;
257 /*
258 * UNIX domain sockets are not supported in NSPR
259 */
260 case EIO: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
261 case EISDIR: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
262 case ELOOP: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
263 case ENOENT: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
264 case ENOTDIR: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
265 case EROFS: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
266 default: nss_MD_unix_map_default_error(err); return;
267 }
268 PR_SetError(prError, err);
269 }
270
nss_MD_unix_map_listen_error(int err)271 void nss_MD_unix_map_listen_error(int err)
272 {
273 nss_MD_unix_map_default_error(err);
274 }
275
nss_MD_unix_map_shutdown_error(int err)276 void nss_MD_unix_map_shutdown_error(int err)
277 {
278 nss_MD_unix_map_default_error(err);
279 }
280
nss_MD_unix_map_socketpair_error(int err)281 void nss_MD_unix_map_socketpair_error(int err)
282 {
283 PRErrorCode prError;
284 switch (err) {
285 case ENOMEM: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
286 default: nss_MD_unix_map_default_error(err); return;
287 }
288 PR_SetError(prError, err);
289 }
290
nss_MD_unix_map_getsockname_error(int err)291 void nss_MD_unix_map_getsockname_error(int err)
292 {
293 PRErrorCode prError;
294 switch (err) {
295 case ENOMEM: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
296 default: nss_MD_unix_map_default_error(err); return;
297 }
298 PR_SetError(prError, err);
299 }
300
nss_MD_unix_map_getpeername_error(int err)301 void nss_MD_unix_map_getpeername_error(int err)
302 {
303 PRErrorCode prError;
304
305 switch (err) {
306 case ENOMEM: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
307 default: nss_MD_unix_map_default_error(err); return;
308 }
309 PR_SetError(prError, err);
310 }
311
nss_MD_unix_map_getsockopt_error(int err)312 void nss_MD_unix_map_getsockopt_error(int err)
313 {
314 PRErrorCode prError;
315 switch (err) {
316 case EINVAL: prError = PR_BUFFER_OVERFLOW_ERROR; break;
317 case ENOMEM: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
318 default: nss_MD_unix_map_default_error(err); return;
319 }
320 PR_SetError(prError, err);
321 }
322
nss_MD_unix_map_setsockopt_error(int err)323 void nss_MD_unix_map_setsockopt_error(int err)
324 {
325 PRErrorCode prError;
326 switch (err) {
327 case EINVAL: prError = PR_BUFFER_OVERFLOW_ERROR; break;
328 case ENOMEM: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
329 default: nss_MD_unix_map_default_error(err); return;
330 }
331 PR_SetError(prError, err);
332 }
333
nss_MD_unix_map_open_error(int err)334 void nss_MD_unix_map_open_error(int err)
335 {
336 PRErrorCode prError;
337 switch (err) {
338 case EAGAIN: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
339 case EBUSY: prError = PR_IO_ERROR; break;
340 case ENODEV: prError = PR_FILE_NOT_FOUND_ERROR; break;
341 case ENOMEM: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
342 case ETIMEDOUT: prError = PR_REMOTE_FILE_ERROR; break;
343 default: nss_MD_unix_map_default_error(err); return;
344 }
345 PR_SetError(prError, err);
346 }
347
nss_MD_unix_map_mmap_error(int err)348 void nss_MD_unix_map_mmap_error(int err)
349 {
350 PRErrorCode prError;
351 switch (err) {
352 case EAGAIN: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
353 case EMFILE: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
354 case ENODEV: prError = PR_OPERATION_NOT_SUPPORTED_ERROR; break;
355 case ENXIO: prError = PR_INVALID_ARGUMENT_ERROR; break;
356 default: nss_MD_unix_map_default_error(err); return;
357 }
358 PR_SetError(prError, err);
359 }
360
nss_MD_unix_map_gethostname_error(int err)361 void nss_MD_unix_map_gethostname_error(int err)
362 {
363 nss_MD_unix_map_default_error(err);
364 }
365
nss_MD_unix_map_select_error(int err)366 void nss_MD_unix_map_select_error(int err)
367 {
368 nss_MD_unix_map_default_error(err);
369 }
370
371 #ifdef _PR_POLL_AVAILABLE
nss_MD_unix_map_poll_error(int err)372 void nss_MD_unix_map_poll_error(int err)
373 {
374 PRErrorCode prError;
375
376 switch (err) {
377 case EAGAIN: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
378 default: nss_MD_unix_map_default_error(err); return;
379 }
380 PR_SetError(prError, err);
381 }
382
nss_MD_unix_map_poll_revents_error(int err)383 void nss_MD_unix_map_poll_revents_error(int err)
384 {
385 if (err & POLLNVAL)
386 PR_SetError(PR_BAD_DESCRIPTOR_ERROR, EBADF);
387 else if (err & POLLHUP)
388 PR_SetError(PR_CONNECT_RESET_ERROR, EPIPE);
389 else if (err & POLLERR)
390 PR_SetError(PR_IO_ERROR, EIO);
391 else
392 PR_SetError(PR_UNKNOWN_ERROR, err);
393 }
394 #endif /* _PR_POLL_AVAILABLE */
395
396
nss_MD_unix_map_flock_error(int err)397 void nss_MD_unix_map_flock_error(int err)
398 {
399 PRErrorCode prError;
400 switch (err) {
401 case EINVAL: prError = PR_BAD_DESCRIPTOR_ERROR; break;
402 case EWOULDBLOCK: prError = PR_FILE_IS_LOCKED_ERROR; break;
403 default: nss_MD_unix_map_default_error(err); return;
404 }
405 PR_SetError(prError, err);
406 }
407
nss_MD_unix_map_lockf_error(int err)408 void nss_MD_unix_map_lockf_error(int err)
409 {
410 PRErrorCode prError;
411 switch (err) {
412 case EACCES: prError = PR_FILE_IS_LOCKED_ERROR; break;
413 case EDEADLK: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
414 default: nss_MD_unix_map_default_error(err); return;
415 }
416 PR_SetError(prError, err);
417 }
418
419 #ifdef HPUX11
nss_MD_hpux_map_sendfile_error(int err)420 void nss_MD_hpux_map_sendfile_error(int err)
421 {
422 nss_MD_unix_map_default_error(err);
423 }
424 #endif /* HPUX11 */
425
426
nss_MD_unix_map_default_error(int err)427 void nss_MD_unix_map_default_error(int err)
428 {
429 PRErrorCode prError;
430 switch (err ) {
431 case EACCES: prError = PR_NO_ACCESS_RIGHTS_ERROR; break;
432 case EADDRINUSE: prError = PR_ADDRESS_IN_USE_ERROR; break;
433 case EADDRNOTAVAIL: prError = PR_ADDRESS_NOT_AVAILABLE_ERROR; break;
434 case EAFNOSUPPORT: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
435 case EAGAIN: prError = PR_WOULD_BLOCK_ERROR; break;
436 /*
437 * On QNX and Neutrino, EALREADY is defined as EBUSY.
438 */
439 #if EALREADY != EBUSY
440 case EALREADY: prError = PR_ALREADY_INITIATED_ERROR; break;
441 #endif
442 case EBADF: prError = PR_BAD_DESCRIPTOR_ERROR; break;
443 #ifdef EBADMSG
444 case EBADMSG: prError = PR_IO_ERROR; break;
445 #endif
446 case EBUSY: prError = PR_FILESYSTEM_MOUNTED_ERROR; break;
447 case ECONNREFUSED: prError = PR_CONNECT_REFUSED_ERROR; break;
448 case ECONNRESET: prError = PR_CONNECT_RESET_ERROR; break;
449 case EDEADLK: prError = PR_DEADLOCK_ERROR; break;
450 #ifdef EDIRCORRUPTED
451 case EDIRCORRUPTED: prError = PR_DIRECTORY_CORRUPTED_ERROR; break;
452 #endif
453 #ifdef EDQUOT
454 case EDQUOT: prError = PR_NO_DEVICE_SPACE_ERROR; break;
455 #endif
456 case EEXIST: prError = PR_FILE_EXISTS_ERROR; break;
457 case EFAULT: prError = PR_ACCESS_FAULT_ERROR; break;
458 case EFBIG: prError = PR_FILE_TOO_BIG_ERROR; break;
459 case EINPROGRESS: prError = PR_IN_PROGRESS_ERROR; break;
460 case EINTR: prError = PR_PENDING_INTERRUPT_ERROR; break;
461 case EINVAL: prError = PR_INVALID_ARGUMENT_ERROR; break;
462 case EIO: prError = PR_IO_ERROR; break;
463 case EISCONN: prError = PR_IS_CONNECTED_ERROR; break;
464 case EISDIR: prError = PR_IS_DIRECTORY_ERROR; break;
465 case ELOOP: prError = PR_LOOP_ERROR; break;
466 case EMFILE: prError = PR_PROC_DESC_TABLE_FULL_ERROR; break;
467 case EMLINK: prError = PR_MAX_DIRECTORY_ENTRIES_ERROR; break;
468 case EMSGSIZE: prError = PR_INVALID_ARGUMENT_ERROR; break;
469 #ifdef EMULTIHOP
470 case EMULTIHOP: prError = PR_REMOTE_FILE_ERROR; break;
471 #endif
472 case ENAMETOOLONG: prError = PR_NAME_TOO_LONG_ERROR; break;
473 case ENETUNREACH: prError = PR_NETWORK_UNREACHABLE_ERROR; break;
474 case ENFILE: prError = PR_SYS_DESC_TABLE_FULL_ERROR; break;
475 #if !defined(SCO)
476 case ENOBUFS: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
477 #endif
478 case ENODEV: prError = PR_FILE_NOT_FOUND_ERROR; break;
479 case ENOENT: prError = PR_FILE_NOT_FOUND_ERROR; break;
480 case ENOLCK: prError = PR_FILE_IS_LOCKED_ERROR; break;
481 #ifdef ENOLINK
482 case ENOLINK: prError = PR_REMOTE_FILE_ERROR; break;
483 #endif
484 case ENOMEM: prError = PR_OUT_OF_MEMORY_ERROR; break;
485 case ENOPROTOOPT: prError = PR_INVALID_ARGUMENT_ERROR; break;
486 case ENOSPC: prError = PR_NO_DEVICE_SPACE_ERROR; break;
487 #ifdef ENOSR
488 case ENOSR: prError = PR_INSUFFICIENT_RESOURCES_ERROR; break;
489 #endif
490 case ENOTCONN: prError = PR_NOT_CONNECTED_ERROR; break;
491 case ENOTDIR: prError = PR_NOT_DIRECTORY_ERROR; break;
492 case ENOTSOCK: prError = PR_NOT_SOCKET_ERROR; break;
493 case ENXIO: prError = PR_FILE_NOT_FOUND_ERROR; break;
494 case EOPNOTSUPP: prError = PR_NOT_TCP_SOCKET_ERROR; break;
495 #ifdef EOVERFLOW
496 case EOVERFLOW: prError = PR_BUFFER_OVERFLOW_ERROR; break;
497 #endif
498 case EPERM: prError = PR_NO_ACCESS_RIGHTS_ERROR; break;
499 case EPIPE: prError = PR_CONNECT_RESET_ERROR; break;
500 #ifdef EPROTO
501 case EPROTO: prError = PR_IO_ERROR; break;
502 #endif
503 case EPROTONOSUPPORT: prError = PR_PROTOCOL_NOT_SUPPORTED_ERROR; break;
504 case EPROTOTYPE: prError = PR_ADDRESS_NOT_SUPPORTED_ERROR; break;
505 case ERANGE: prError = PR_INVALID_METHOD_ERROR; break;
506 case EROFS: prError = PR_READ_ONLY_FILESYSTEM_ERROR; break;
507 case ESPIPE: prError = PR_INVALID_METHOD_ERROR; break;
508 case ETIMEDOUT: prError = PR_IO_TIMEOUT_ERROR; break;
509 #if EWOULDBLOCK != EAGAIN
510 case EWOULDBLOCK: prError = PR_WOULD_BLOCK_ERROR; break;
511 #endif
512 case EXDEV: prError = PR_NOT_SAME_DEVICE_ERROR; break;
513
514 default: prError = PR_UNKNOWN_ERROR; break;
515 }
516 PR_SetError(prError, err);
517 }
518