Home | History | Annotate | Download | only in ssl
      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