Home | History | Annotate | Download | only in include
      1 /*
      2  * Copyright 2014, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15 */
     16 
     17 #ifndef _ERRNO_PORTABLE_H_
     18 #define _ERRNO_PORTABLE_H_
     19 
     20 #include <portability.h>
     21 #include <errno.h>
     22 #include <pthread.h>
     23 #include <string.h>
     24 
     25 #define ALOGV(...)
     26 
     27 #define EDEADLK_PORTABLE 35
     28 #define ENAMETOOLONG_PORTABLE 36
     29 #define ENOLCK_PORTABLE 37
     30 #define ENOSYS_PORTABLE 38
     31 #define ENOTEMPTY_PORTABLE 39
     32 #define ELOOP_PORTABLE 40
     33 #define EWOULDBLOCK_PORTABLE 11 /* EAGAIN */
     34 #define ENOMSG_PORTABLE 42
     35 #define EIDRM_PORTABLE 43
     36 #define ECHRNG_PORTABLE 44
     37 #define EL2NSYNC_PORTABLE 45
     38 #define EL3HLT_PORTABLE 46
     39 #define EL3RST_PORTABLE 47
     40 #define ELNRNG_PORTABLE 48
     41 #define EUNATCH_PORTABLE 49
     42 #define ENOCSI_PORTABLE 50
     43 #define EL2HLT_PORTABLE 51
     44 #define EBADE_PORTABLE 52
     45 #define EBADR_PORTABLE 53
     46 #define EXFULL_PORTABLE 54
     47 #define ENOANO_PORTABLE 55
     48 #define EBADRQC_PORTABLE 56
     49 #define EBADSLT_PORTABLE 57
     50 
     51 #define EDEADLOCK_PORTABLE EDEADLK_PORTABLE
     52 
     53 #define EBFONT_PORTABLE 59
     54 #define ENOSTR_PORTABLE 60
     55 #define ENODATA_PORTABLE 61
     56 #define ETIME_PORTABLE 62
     57 #define ENOSR_PORTABLE 63
     58 #define ENONET_PORTABLE 64
     59 #define ENOPKG_PORTABLE 65
     60 #define EREMOTE_PORTABLE 66
     61 #define ENOLINK_PORTABLE 67
     62 #define EADV_PORTABLE 68
     63 #define ESRMNT_PORTABLE 69
     64 #define ECOMM_PORTABLE 70
     65 #define EPROTO_PORTABLE 71
     66 #define EMULTIHOP_PORTABLE 72
     67 #define EDOTDOT_PORTABLE 73
     68 #define EBADMSG_PORTABLE 74
     69 #define EOVERFLOW_PORTABLE 75
     70 #define ENOTUNIQ_PORTABLE 76
     71 #define EBADFD_PORTABLE 77
     72 #define EREMCHG_PORTABLE 78
     73 #define ELIBACC_PORTABLE 79
     74 #define ELIBBAD_PORTABLE 80
     75 #define ELIBSCN_PORTABLE 81
     76 #define ELIBMAX_PORTABLE 82
     77 #define ELIBEXEC_PORTABLE 83
     78 #define EILSEQ_PORTABLE 84
     79 #define ERESTART_PORTABLE 85
     80 #define ESTRPIPE_PORTABLE 86
     81 #define EUSERS_PORTABLE 87
     82 #define ENOTSOCK_PORTABLE 88
     83 #define EDESTADDRREQ_PORTABLE 89
     84 #define EMSGSIZE_PORTABLE 90
     85 #define EPROTOTYPE_PORTABLE 91
     86 #define ENOPROTOOPT_PORTABLE 92
     87 #define EPROTONOSUPPORT_PORTABLE 93
     88 #define ESOCKTNOSUPPORT_PORTABLE 94
     89 #define EOPNOTSUPP_PORTABLE 95
     90 #define EPFNOSUPPORT_PORTABLE 96
     91 #define EAFNOSUPPORT_PORTABLE 97
     92 #define EADDRINUSE_PORTABLE 98
     93 #define EADDRNOTAVAIL_PORTABLE 99
     94 #define ENETDOWN_PORTABLE 100
     95 #define ENETUNREACH_PORTABLE 101
     96 #define ENETRESET_PORTABLE 102
     97 #define ECONNABORTED_PORTABLE 103
     98 #define ECONNRESET_PORTABLE 104
     99 #define ENOBUFS_PORTABLE 105
    100 #define EISCONN_PORTABLE 106
    101 #define ENOTCONN_PORTABLE 107
    102 #define ESHUTDOWN_PORTABLE 108
    103 #define ETOOMANYREFS_PORTABLE 109
    104 #define ETIMEDOUT_PORTABLE 110
    105 #define ECONNREFUSED_PORTABLE 111
    106 #define EHOSTDOWN_PORTABLE 112
    107 #define EHOSTUNREACH_PORTABLE 113
    108 #define EALREADY_PORTABLE 114
    109 #define EINPROGRESS_PORTABLE 115
    110 #define ESTALE_PORTABLE 116
    111 #define EUCLEAN_PORTABLE 117
    112 #define ENOTNAM_PORTABLE 118
    113 #define ENAVAIL_PORTABLE 119
    114 #define EISNAM_PORTABLE 120
    115 #define EREMOTEIO_PORTABLE 121
    116 #define EDQUOT_PORTABLE 122
    117 
    118 #define ENOMEDIUM_PORTABLE 123
    119 #define EMEDIUMTYPE_PORTABLE 124
    120 #define ECANCELED_PORTABLE 125
    121 #define ENOKEY_PORTABLE 126
    122 #define EKEYEXPIRED_PORTABLE 127
    123 #define EKEYREVOKED_PORTABLE 128
    124 #define EKEYREJECTED_PORTABLE 129
    125 
    126 #define EOWNERDEAD_PORTABLE 130
    127 #define ENOTRECOVERABLE_PORTABLE 131
    128 #define ERFKILL_PORTABLE 132
    129 #define EHWPOISON_PORTABLE 133
    130 
    131 extern volatile int* REAL(__errno)();
    132 
    133 static int errno_ntop(int native_errno)
    134 {
    135     switch (native_errno) {
    136       case ENAMETOOLONG: return ENAMETOOLONG_PORTABLE;
    137       case ENOLCK: return ENOLCK_PORTABLE;
    138       case ENOSYS: return ENOSYS_PORTABLE;
    139       case ENOTEMPTY: return ENOTEMPTY_PORTABLE;
    140       case ELOOP: return ELOOP_PORTABLE;
    141       case EWOULDBLOCK: return EWOULDBLOCK_PORTABLE;
    142       case ENOMSG: return ENOMSG_PORTABLE;
    143       case EIDRM: return EIDRM_PORTABLE;
    144       case ECHRNG: return ECHRNG_PORTABLE;
    145       case EL2NSYNC: return EL2NSYNC_PORTABLE;
    146       case EL3HLT: return EL3HLT_PORTABLE;
    147       case EL3RST: return EL3RST_PORTABLE;
    148       case ELNRNG: return ELNRNG_PORTABLE;
    149       case EUNATCH: return EUNATCH_PORTABLE;
    150       case ENOCSI: return ENOCSI_PORTABLE;
    151       case EL2HLT: return EL2HLT_PORTABLE;
    152       case EBADE: return EBADE_PORTABLE;
    153       case EBADR: return EBADR_PORTABLE;
    154       case EXFULL: return EXFULL_PORTABLE;
    155       case ENOANO: return ENOANO_PORTABLE;
    156       case EBADRQC: return EBADRQC_PORTABLE;
    157       case EBADSLT: return EBADSLT_PORTABLE;
    158       case EDEADLOCK: return EDEADLOCK_PORTABLE;
    159       case EBFONT: return EBFONT_PORTABLE;
    160       case ENOSTR: return ENOSTR_PORTABLE;
    161       case ENODATA: return ENODATA_PORTABLE;
    162       case ETIME: return ETIME_PORTABLE;
    163       case ENOSR: return ENOSR_PORTABLE;
    164       case ENONET: return ENONET_PORTABLE;
    165       case ENOPKG: return ENOPKG_PORTABLE;
    166       case EREMOTE: return EREMOTE_PORTABLE;
    167       case ENOLINK: return ENOLINK_PORTABLE;
    168       case EADV: return EADV_PORTABLE;
    169       case ESRMNT: return ESRMNT_PORTABLE;
    170       case ECOMM: return ECOMM_PORTABLE;
    171       case EPROTO: return EPROTO_PORTABLE;
    172       case EMULTIHOP: return EMULTIHOP_PORTABLE;
    173       case EDOTDOT: return EDOTDOT_PORTABLE;
    174       case EBADMSG: return EBADMSG_PORTABLE;
    175       case EOVERFLOW: return EOVERFLOW_PORTABLE;
    176       case ENOTUNIQ: return ENOTUNIQ_PORTABLE;
    177       case EBADFD: return EBADFD_PORTABLE;
    178       case EREMCHG: return EREMCHG_PORTABLE;
    179       case ELIBACC: return ELIBACC_PORTABLE;
    180       case ELIBBAD: return ELIBBAD_PORTABLE;
    181       case ELIBSCN: return ELIBSCN_PORTABLE;
    182       case ELIBMAX: return ELIBMAX_PORTABLE;
    183       case ELIBEXEC: return ELIBEXEC_PORTABLE;
    184       case EILSEQ: return EILSEQ_PORTABLE;
    185       case ERESTART: return ERESTART_PORTABLE;
    186       case ESTRPIPE: return ESTRPIPE_PORTABLE;
    187       case EUSERS: return EUSERS_PORTABLE;
    188       case ENOTSOCK: return ENOTSOCK_PORTABLE;
    189       case EDESTADDRREQ: return EDESTADDRREQ_PORTABLE;
    190       case EMSGSIZE: return EMSGSIZE_PORTABLE;
    191       case EPROTOTYPE: return EPROTOTYPE_PORTABLE;
    192       case ENOPROTOOPT: return ENOPROTOOPT_PORTABLE;
    193       case EPROTONOSUPPORT: return EPROTONOSUPPORT_PORTABLE;
    194       case ESOCKTNOSUPPORT: return ESOCKTNOSUPPORT_PORTABLE;
    195       case EOPNOTSUPP: return EOPNOTSUPP_PORTABLE;
    196       case EPFNOSUPPORT: return EPFNOSUPPORT_PORTABLE;
    197       case EAFNOSUPPORT: return EAFNOSUPPORT_PORTABLE;
    198       case EADDRINUSE: return EADDRINUSE_PORTABLE;
    199       case EADDRNOTAVAIL: return EADDRNOTAVAIL_PORTABLE;
    200       case ENETDOWN: return ENETDOWN_PORTABLE;
    201       case ENETUNREACH: return ENETUNREACH_PORTABLE;
    202       case ENETRESET: return ENETRESET_PORTABLE;
    203       case ECONNABORTED: return ECONNABORTED_PORTABLE;
    204       case ECONNRESET: return ECONNRESET_PORTABLE;
    205       case ENOBUFS: return ENOBUFS_PORTABLE;
    206       case EISCONN: return EISCONN_PORTABLE;
    207       case ENOTCONN: return ENOTCONN_PORTABLE;
    208       case ESHUTDOWN: return ESHUTDOWN_PORTABLE;
    209       case ETOOMANYREFS: return ETOOMANYREFS_PORTABLE;
    210       case ETIMEDOUT: return ETIMEDOUT_PORTABLE;
    211       case ECONNREFUSED: return ECONNREFUSED_PORTABLE;
    212       case EHOSTDOWN: return EHOSTDOWN_PORTABLE;
    213       case EHOSTUNREACH: return EHOSTUNREACH_PORTABLE;
    214       case EALREADY: return EALREADY_PORTABLE;
    215       case EINPROGRESS: return EINPROGRESS_PORTABLE;
    216       case ESTALE: return ESTALE_PORTABLE;
    217       case EUCLEAN: return EUCLEAN_PORTABLE;
    218       case ENOTNAM: return ENOTNAM_PORTABLE;
    219       case ENAVAIL: return ENAVAIL_PORTABLE;
    220       case EISNAM: return EISNAM_PORTABLE;
    221       case EREMOTEIO: return EREMOTEIO_PORTABLE;
    222       case EDQUOT: return EDQUOT_PORTABLE;
    223       case ENOMEDIUM: return ENOMEDIUM_PORTABLE;
    224       case EMEDIUMTYPE: return EMEDIUMTYPE_PORTABLE;
    225       case ECANCELED: return ECANCELED_PORTABLE;
    226       case ENOKEY: return ENOKEY_PORTABLE;
    227       case EKEYEXPIRED: return EKEYEXPIRED_PORTABLE;
    228       case EKEYREVOKED: return EKEYREVOKED_PORTABLE;
    229       case EKEYREJECTED: return EKEYREJECTED_PORTABLE;
    230       case EOWNERDEAD: return EOWNERDEAD_PORTABLE;
    231       case ENOTRECOVERABLE: return ENOTRECOVERABLE_PORTABLE;
    232     }
    233     return native_errno;
    234 }
    235 
    236 static int errno_pton(int portable_errno)
    237 {
    238     switch (portable_errno) {
    239       case ENAMETOOLONG_PORTABLE: return ENAMETOOLONG;
    240       case ENOLCK_PORTABLE: return ENOLCK;
    241       case ENOSYS_PORTABLE: return ENOSYS;
    242       case ENOTEMPTY_PORTABLE: return ENOTEMPTY;
    243       case ELOOP_PORTABLE: return ELOOP;
    244       case EWOULDBLOCK_PORTABLE: return EWOULDBLOCK;
    245       case ENOMSG_PORTABLE: return ENOMSG;
    246       case EIDRM_PORTABLE: return EIDRM;
    247       case ECHRNG_PORTABLE: return ECHRNG;
    248       case EL2NSYNC_PORTABLE: return EL2NSYNC;
    249       case EL3HLT_PORTABLE: return EL3HLT;
    250       case EL3RST_PORTABLE: return EL3RST;
    251       case ELNRNG_PORTABLE: return ELNRNG;
    252       case EUNATCH_PORTABLE: return EUNATCH;
    253       case ENOCSI_PORTABLE: return ENOCSI;
    254       case EL2HLT_PORTABLE: return EL2HLT;
    255       case EBADE_PORTABLE: return EBADE;
    256       case EBADR_PORTABLE: return EBADR;
    257       case EXFULL_PORTABLE: return EXFULL;
    258       case ENOANO_PORTABLE: return ENOANO;
    259       case EBADRQC_PORTABLE: return EBADRQC;
    260       case EBADSLT_PORTABLE: return EBADSLT;
    261       case EDEADLOCK_PORTABLE: return EDEADLOCK;
    262       case EBFONT_PORTABLE: return EBFONT;
    263       case ENOSTR_PORTABLE: return ENOSTR;
    264       case ENODATA_PORTABLE: return ENODATA;
    265       case ETIME_PORTABLE: return ETIME;
    266       case ENOSR_PORTABLE: return ENOSR;
    267       case ENONET_PORTABLE: return ENONET;
    268       case ENOPKG_PORTABLE: return ENOPKG;
    269       case EREMOTE_PORTABLE: return EREMOTE;
    270       case ENOLINK_PORTABLE: return ENOLINK;
    271       case EADV_PORTABLE: return EADV;
    272       case ESRMNT_PORTABLE: return ESRMNT;
    273       case ECOMM_PORTABLE: return ECOMM;
    274       case EPROTO_PORTABLE: return EPROTO;
    275       case EMULTIHOP_PORTABLE: return EMULTIHOP;
    276       case EDOTDOT_PORTABLE: return EDOTDOT;
    277       case EBADMSG_PORTABLE: return EBADMSG;
    278       case EOVERFLOW_PORTABLE: return EOVERFLOW;
    279       case ENOTUNIQ_PORTABLE: return ENOTUNIQ;
    280       case EBADFD_PORTABLE: return EBADFD;
    281       case EREMCHG_PORTABLE: return EREMCHG;
    282       case ELIBACC_PORTABLE: return ELIBACC;
    283       case ELIBBAD_PORTABLE: return ELIBBAD;
    284       case ELIBSCN_PORTABLE: return ELIBSCN;
    285       case ELIBMAX_PORTABLE: return ELIBMAX;
    286       case ELIBEXEC_PORTABLE: return ELIBEXEC;
    287       case EILSEQ_PORTABLE: return EILSEQ;
    288       case ERESTART_PORTABLE: return ERESTART;
    289       case ESTRPIPE_PORTABLE: return ESTRPIPE;
    290       case EUSERS_PORTABLE: return EUSERS;
    291       case ENOTSOCK_PORTABLE: return ENOTSOCK;
    292       case EDESTADDRREQ_PORTABLE: return EDESTADDRREQ;
    293       case EMSGSIZE_PORTABLE: return EMSGSIZE;
    294       case EPROTOTYPE_PORTABLE: return EPROTOTYPE;
    295       case ENOPROTOOPT_PORTABLE: return ENOPROTOOPT;
    296       case EPROTONOSUPPORT_PORTABLE: return EPROTONOSUPPORT;
    297       case ESOCKTNOSUPPORT_PORTABLE: return ESOCKTNOSUPPORT;
    298       case EOPNOTSUPP_PORTABLE: return EOPNOTSUPP;
    299       case EPFNOSUPPORT_PORTABLE: return EPFNOSUPPORT;
    300       case EAFNOSUPPORT_PORTABLE: return EAFNOSUPPORT;
    301       case EADDRINUSE_PORTABLE: return EADDRINUSE;
    302       case EADDRNOTAVAIL_PORTABLE: return EADDRNOTAVAIL;
    303       case ENETDOWN_PORTABLE: return ENETDOWN;
    304       case ENETUNREACH_PORTABLE: return ENETUNREACH;
    305       case ENETRESET_PORTABLE: return ENETRESET;
    306       case ECONNABORTED_PORTABLE: return ECONNABORTED;
    307       case ECONNRESET_PORTABLE: return ECONNRESET;
    308       case ENOBUFS_PORTABLE: return ENOBUFS;
    309       case EISCONN_PORTABLE: return EISCONN;
    310       case ENOTCONN_PORTABLE: return ENOTCONN;
    311       case ESHUTDOWN_PORTABLE: return ESHUTDOWN;
    312       case ETOOMANYREFS_PORTABLE: return ETOOMANYREFS;
    313       case ETIMEDOUT_PORTABLE: return ETIMEDOUT;
    314       case ECONNREFUSED_PORTABLE: return ECONNREFUSED;
    315       case EHOSTDOWN_PORTABLE: return EHOSTDOWN;
    316       case EHOSTUNREACH_PORTABLE: return EHOSTUNREACH;
    317       case EALREADY_PORTABLE: return EALREADY;
    318       case EINPROGRESS_PORTABLE: return EINPROGRESS;
    319       case ESTALE_PORTABLE: return ESTALE;
    320       case EUCLEAN_PORTABLE: return EUCLEAN;
    321       case ENOTNAM_PORTABLE: return ENOTNAM;
    322       case ENAVAIL_PORTABLE: return ENAVAIL;
    323       case EISNAM_PORTABLE: return EISNAM;
    324       case EREMOTEIO_PORTABLE: return EREMOTEIO;
    325       case EDQUOT_PORTABLE: return EDQUOT;
    326       case ENOMEDIUM_PORTABLE: return ENOMEDIUM;
    327       case EMEDIUMTYPE_PORTABLE: return EMEDIUMTYPE;
    328       case ECANCELED_PORTABLE: return ECANCELED;
    329       case ENOKEY_PORTABLE: return ENOKEY;
    330       case EKEYEXPIRED_PORTABLE: return EKEYEXPIRED;
    331       case EKEYREVOKED_PORTABLE: return EKEYREVOKED;
    332       case EKEYREJECTED_PORTABLE: return EKEYREJECTED;
    333       case EOWNERDEAD_PORTABLE: return EOWNERDEAD;
    334       case ENOTRECOVERABLE_PORTABLE: return ENOTRECOVERABLE;
    335     }
    336     return portable_errno;
    337 }
    338 
    339 /* Key for the thread-specific portable errno */
    340 static pthread_key_t errno_key;
    341 
    342 /* Once-only initialisation of the key */
    343 static pthread_once_t errno_key_once = PTHREAD_ONCE_INIT;
    344 
    345 /* Free the thread-specific portable errno */
    346 static void errno_key_destroy(void *buf)
    347 {
    348     if (buf)
    349         free(buf);
    350 }
    351 
    352 /* Allocate the key */
    353 static void errno_key_create(void)
    354 {
    355     pthread_key_create(&errno_key, errno_key_destroy);
    356 }
    357 
    358 struct errno_state {
    359     int pshadow;                /* copy of last portable errno */
    360     int perrno;                 /* portable errno that may be modified by app */
    361 };
    362 
    363 /* Return the thread-specific portable errno */
    364 static struct errno_state *errno_key_data(void)
    365 {
    366     struct errno_state *data;
    367     static struct errno_state errno_state;
    368 
    369     pthread_once(&errno_key_once, errno_key_create);
    370     data = (struct errno_state *)pthread_getspecific(errno_key);
    371     if (data == NULL) {
    372         data = malloc(sizeof(struct errno_state));
    373         pthread_setspecific(errno_key, data);
    374     }
    375     if (data == NULL)
    376         data = &errno_state;
    377     return data;
    378 }
    379 
    380 /*
    381  * Attempt to return a thread specific location containnig the portable errno.
    382  * This can be assigned to without affecting the native errno. If the key
    383  * allocation fails fall back to using the native errno location.
    384  */
    385 volatile int* WRAP(__errno)()
    386 {
    387     struct errno_state *p;
    388     int save_errno;
    389 
    390     /* pthread_* calls may modify errno so use a copy */
    391     save_errno = *REAL(__errno)();
    392 
    393     p = errno_key_data();
    394 
    395     ALOGV(" ");
    396     ALOGV("%s(): { save_errno = errno:%d, (p:%p)->{pshadow:%d, perrno:%d}", __func__,
    397                    save_errno,             p,   p->pshadow, p->perrno);
    398 
    399     if (save_errno == 0 && p->pshadow != p->perrno) {
    400         /*
    401          * portable errno has changed but native hasn't
    402          * - copy portable error back to native
    403          */
    404         p->pshadow = p->perrno;
    405         save_errno = errno_pton(p->perrno);
    406     }
    407     else if (save_errno != 0 && p->pshadow == p->perrno) {
    408         /*
    409          * Native errno has changed but portable hasn't
    410          * - copy native error to portable.
    411          */
    412         p->pshadow = p->perrno = errno_ntop(save_errno);
    413         save_errno = 0;
    414     }
    415     else if (save_errno != 0 && p->pshadow != p->perrno) {
    416         /*
    417          * Both native and portable errno values have changed
    418          * so give priority to native errno
    419          * - copy native error to portable
    420          */
    421         p->pshadow = p->perrno = errno_ntop(save_errno);
    422         save_errno = 0;
    423     }
    424 
    425     ALOGV("%s: new save_errno:%d p:%p->{pshadow:%d, perrno:%d}", __func__,
    426                    save_errno,   p,  p->pshadow, p->perrno);
    427 
    428     *REAL(__errno)() = save_errno;
    429 
    430     ALOGV("%s: return (&p->perrno):%p; }", __func__, &p->perrno);
    431 
    432     /* return pointer to the modifiable portable errno value */
    433     return &p->perrno;
    434 }
    435 
    436 
    437 /* set portable errno */
    438 void WRAP(__set_errno)(int portable_errno)
    439 {
    440     struct errno_state *p;
    441     int save_errno;
    442 
    443     /* pthread_* calls may modify errno so use a copy */
    444     save_errno = *REAL(__errno)();
    445 
    446     p = errno_key_data();
    447 
    448     ALOGV("%s(): { save_errno = errno:%d, p:%p->{pshadow:%d, perrno:%d}", __func__,
    449                    save_errno,            p,  p->pshadow, p->perrno);
    450 
    451     p->pshadow = p->perrno = portable_errno;
    452 
    453     save_errno = errno_pton(portable_errno);
    454 
    455     ALOGV("%s: new save_errno:%d, p:%p->{pshadow:%d, perrno:%d}", __func__,
    456                    save_errno,    p,  p->pshadow, p->perrno);
    457 
    458     *REAL(__errno)() = save_errno;
    459 
    460     ALOGV("%s: return; }", __func__);
    461 }
    462 
    463 extern char* REAL(strerror)(int);
    464 char *WRAP(strerror)(int errnum)
    465 {
    466     return REAL(strerror)(errno_pton(errnum));
    467 }
    468 
    469 /* BSD style strerror_r */
    470 int WRAP(strerror_r)(int errnum, char *buf, size_t buflen)
    471 {
    472     return REAL(strerror_r)(errno_pton(errnum), buf, buflen);
    473 }
    474 #endif /* _ERRNO_PORTABLE_H */
    475