1 /* $OpenBSD: errno.c,v 1.6 2016/05/07 19:05:22 guenther Exp $ */ 2 /* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */ 3 4 #include <tib.h> 5 #include <errno.h> 6 #include <unistd.h> 7 #include "thread_private.h" 8 9 10 #ifdef TCB_HAVE_MD_GET 11 /* 12 * If there's an MD TCB_GET() macro, then getting the TCB address is 13 * cheap enough that we can do it even in single-threaded programs, 14 * so the tc_errnoptr and tc_tcb callbacks will be unused, and __errno() 15 * can just use TIB_GET(). 16 */ 17 int * __errno(void)18__errno(void) 19 { 20 return (&TIB_GET()->tib_errno); 21 } 22 DEF_STRONG(__errno); 23 24 #else /* ! TCB_HAVE_MD_GET */ 25 /* 26 * Otherwise, getting the TCB address requires the __get_tcb() 27 * syscall. Rather than pay that cost for single-threaded programs, 28 * the syscall stubs will invoke the tc_errnoptr callback to set errno 29 * and other code will invoke the tc_tcb callback to get the TCB 30 * for cancelation checks, etc. The default callbacks will just 31 * work from the cached location of the initial thread's TCB; 32 * libpthread can override them to the necessary more expensive 33 * versions that use __get_tcb(). 34 */ 35 36 /* cached pointer to the TCB of the only thread in single-threaded programs */ 37 void *_libc_single_tcb = NULL; 38 39 static inline void * single_threaded_tcb(void)40single_threaded_tcb(void) 41 { 42 if (__predict_false(_libc_single_tcb == NULL)) 43 _libc_single_tcb = TCB_GET(); 44 return (_libc_single_tcb); 45 } 46 47 static int * single_threaded_errnoptr(void)48single_threaded_errnoptr(void) 49 { 50 return &TCB_TO_TIB(single_threaded_tcb())->tib_errno; 51 } 52 53 /* 54 * __errno(): just use the callback to get the applicable current method 55 */ 56 int * __errno(void)57__errno(void) 58 { 59 return (_thread_cb.tc_errnoptr()); 60 } 61 DEF_STRONG(__errno); 62 63 #endif /* !TCB_HAVE_MD_GET */ 64 65 66 struct thread_callbacks _thread_cb = 67 { 68 #ifndef TCB_HAVE_MD_GET 69 .tc_errnoptr = &single_threaded_errnoptr, 70 .tc_tcb = &single_threaded_tcb, 71 #endif 72 }; 73