Each thread has its own instance of each library error variable, such as t_errno. Typically, each library error variable is actually defined as a macro such as:
#define t_errno (*(_t_errno()))Unlike storage for the thread-specific errno, which is allocated when a thread is created, storage for each thread-specific library error variable is allocated by the relevant library at the first reference to the variable. In conditions of low memory, the allocation will fail. In the case of t_errno, the function in the error variable macro will return the address of a global variable shared by all threads (a kind of overflow location). In the case of all other library error variables, the function will return NULL. If you try to assign a value to t_errno when the macro function has returned the address of the common global location, the value may later be overwritten by another thread. If you try to assign a value to an error variable when the macro function has returned NULL, you will cause a fatal error (a segmentation violation). For these reasons, the networking libraries do not access library error variables directly. Instead, they use a family of access functions. These access functions are also available for your use in multithreaded applications and applications that you may multithread later.
For example, the function get_t_errno(SLIB) returns the value of t_errno for the current thread. A corresponding function, set_t_errno, sets the value of t_errno for the current thread. (In general, you should avoid setting library error variables, since they are intended to be set only by library functions.)
The library error variables access functions are listed in ``Routines for accessing library error variables''.
Routines for accessing library error variables
|Error variable||Get function||Set function|