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 33 void nss_MD_unix_map_opendir_error(int err) 34 { 35 nss_MD_unix_map_default_error(err); 36 } 37 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 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 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 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 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 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 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 114 void nss_MD_unix_map_mkdir_error(int err) 115 { 116 nss_MD_unix_map_default_error(err); 117 } 118 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 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 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 155 void nss_MD_unix_map_lseek_error(int err) 156 { 157 nss_MD_unix_map_default_error(err); 158 } 159 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 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 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 191 void nss_MD_unix_map_socketavailable_error(int err) 192 { 193 PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err); 194 } 195 196 void nss_MD_unix_map_recv_error(int err) 197 { 198 nss_MD_unix_map_default_error(err); 199 } 200 201 void nss_MD_unix_map_recvfrom_error(int err) 202 { 203 nss_MD_unix_map_default_error(err); 204 } 205 206 void nss_MD_unix_map_send_error(int err) 207 { 208 nss_MD_unix_map_default_error(err); 209 } 210 211 void nss_MD_unix_map_sendto_error(int err) 212 { 213 nss_MD_unix_map_default_error(err); 214 } 215 216 void nss_MD_unix_map_writev_error(int err) 217 { 218 nss_MD_unix_map_default_error(err); 219 } 220 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 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 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 271 void nss_MD_unix_map_listen_error(int err) 272 { 273 nss_MD_unix_map_default_error(err); 274 } 275 276 void nss_MD_unix_map_shutdown_error(int err) 277 { 278 nss_MD_unix_map_default_error(err); 279 } 280 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 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 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 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 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 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 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 361 void nss_MD_unix_map_gethostname_error(int err) 362 { 363 nss_MD_unix_map_default_error(err); 364 } 365 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 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 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 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 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 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 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