X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/6d2010ae8f7a6078e10b361c6962983bab233e0f..7e41aa883dd258f888d0470250eead40a53ef1f5:/libsyscall/custom/errno.c?ds=sidebyside diff --git a/libsyscall/custom/errno.c b/libsyscall/custom/errno.c index 58da2c114..86f754a65 100644 --- a/libsyscall/custom/errno.c +++ b/libsyscall/custom/errno.c @@ -26,4 +26,54 @@ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ +#include +#include +#include +#include "tsd.h" + +/* + * cerror takes the return value of the syscall, being non-zero, and + * stores it in errno. It needs to return -1 to indicate failure but + * 64-bit platforms need to ensure that possible 128-bit wide return + * values are also properly set. + */ +#ifdef __LP64__ +typedef unsigned __int128 cerror_return_t; +#else +typedef uint64_t cerror_return_t; +#endif + +extern void _pthread_exit_if_canceled(int error); + +#undef errno int errno; + +int * +__error(void) +{ + void *ptr = _os_tsd_get_direct(__TSD_ERRNO); + if (ptr != NULL) { + return (int*)ptr; + } + return &errno; +} + +__attribute__((noinline)) +cerror_return_t +cerror_nocancel(int err) +{ + errno = err; + int *tsderrno = (int*)_os_tsd_get_direct(__TSD_ERRNO); + if (tsderrno) { + *tsderrno = err; + } + return -1; +} + +__attribute__((noinline)) +cerror_return_t +cerror(int err) +{ + _pthread_exit_if_canceled(err); + return cerror_nocancel(err); +}