GETC_UNLOCKED(3)           POSIX Programmer's Manual          GETC_UNLOCKED(3)



PPRROOLLOOGG
       This manual page is part of the POSIX Programmer's Manual.  The OS
       implementation of this interface may differ (consult the corresponding
       OS manual page for details of OS behavior), or the interface may not be
       implemented on OS.


NNAAMMEE
       getc_unlocked, getchar_unlocked, putc_unlocked, putchar_unlocked --
       stdio with explicit client locking

SSYYNNOOPPSSIISS
       #include <stdio.h>

       int getc_unlocked(FILE *_s_t_r_e_a_m);
       int getchar_unlocked(void);
       int putc_unlocked(int _c, FILE *_s_t_r_e_a_m);
       int putchar_unlocked(int _c);

DDEESSCCRRIIPPTTIIOONN
       Versions of the functions _g_e_t_c(), _g_e_t_c_h_a_r(), _p_u_t_c(), and _p_u_t_c_h_a_r()
       respectively named _g_e_t_c___u_n_l_o_c_k_e_d(), _g_e_t_c_h_a_r___u_n_l_o_c_k_e_d(),
       _p_u_t_c___u_n_l_o_c_k_e_d(), and _p_u_t_c_h_a_r___u_n_l_o_c_k_e_d() shall be provided which are
       functionally equivalent to the original versions, with the exception
       that they are not required to be implemented in a thread-safe manner.
       They may only safely be used within a scope protected by _f_l_o_c_k_f_i_l_e()
       (or _f_t_r_y_l_o_c_k_f_i_l_e()) and _f_u_n_l_o_c_k_f_i_l_e().  These functions may safely be
       used in a multi-threaded program if and only if they are called while
       the invoking thread owns the (FFIILLEE **) object, as is the case after a
       successful call to the _f_l_o_c_k_f_i_l_e() or _f_t_r_y_l_o_c_k_f_i_l_e() functions.

       If _g_e_t_c___u_n_l_o_c_k_e_d() or _p_u_t_c___u_n_l_o_c_k_e_d() are implemented as macros they
       may evaluate _s_t_r_e_a_m more than once, so the _s_t_r_e_a_m argument should never
       be an expression with side-effects.

RREETTUURRNN VVAALLUUEE
       See _g_e_t_c(), _g_e_t_c_h_a_r(), _p_u_t_c(), and _p_u_t_c_h_a_r().

EERRRROORRSS
       See _g_e_t_c(), _g_e_t_c_h_a_r(), _p_u_t_c(), and _p_u_t_c_h_a_r().

       _T_h_e _f_o_l_l_o_w_i_n_g _s_e_c_t_i_o_n_s _a_r_e _i_n_f_o_r_m_a_t_i_v_e_.

EEXXAAMMPPLLEESS
       None.

AAPPPPLLIICCAATTIIOONN UUSSAAGGEE
       Since they may be implemented as macros, _g_e_t_c___u_n_l_o_c_k_e_d() and
       _p_u_t_c___u_n_l_o_c_k_e_d() may treat incorrectly a _s_t_r_e_a_m argument with side-
       effects. In particular, _g_e_t_c___u_n_l_o_c_k_e_d(*f++) and _p_u_t_c___u_n_l_o_c_k_e_d(c,*f++)
       do not necessarily work as expected.  Therefore, use of these functions
       in such situations should be preceded by the following statement as
       appropriate:

           ##uunnddeeff ggeettcc__uunnlloocckkeedd
           ##uunnddeeff ppuuttcc__uunnlloocckkeedd

RRAATTIIOONNAALLEE
       Some I/O functions are typically implemented as macros for performance
       reasons (for example, _p_u_t_c() and _g_e_t_c()).  For safety, they need to be
       synchronized, but it is often too expensive to synchronize on every
       character. Nevertheless, it was felt that the safety concerns were more
       important; consequently, the _g_e_t_c(), _g_e_t_c_h_a_r(), _p_u_t_c(), and _p_u_t_c_h_a_r()
       functions are required to be thread-safe. However, unlocked versions
       are also provided with names that clearly indicate the unsafe nature of
       their operation but can be used to exploit their higher performance.
       These unlocked versions can be safely used only within explicitly
       locked program regions, using exported locking primitives. In
       particular, a sequence such as:

           fflloocckkffiillee((ffiilleeppttrr));;
           ppuuttcc__uunnlloocckkeedd((''11'',, ffiilleeppttrr));;
           ppuuttcc__uunnlloocckkeedd((''\\nn'',, ffiilleeppttrr));;
           ffpprriinnttff((ffiilleeppttrr,, ""LLiinnee 22\\nn""));;
           ffuunnlloocckkffiillee((ffiilleeppttrr));;

       is permissible, and results in the text sequence:

           11
           LLiinnee 22

       being printed without being interspersed with output from other
       threads.

       It would be wrong to have the standard names such as _g_e_t_c(), _p_u_t_c(),
       and so on, map to the ``faster, but unsafe'' rather than the ``slower,
       but safe'' versions. In either case, you would still want to inspect
       all uses of _g_e_t_c(), _p_u_t_c(), and so on, by hand when converting existing
       code. Choosing the safe bindings as the default, at least, results in
       correct code and maintains the ``atomicity at the function'' invariant.
       To do otherwise would introduce gratuitous synchronization errors into
       converted code.  Other routines that modify the _s_t_d_i_o (FFIILLEE **)
       structures or buffers are also safely synchronized.

       Note that there is no need for functions of the form _g_e_t_c___l_o_c_k_e_d(),
       _p_u_t_c___l_o_c_k_e_d(), and so on, since this is the functionality of _g_e_t_c(),
       _p_u_t_c(), _e_t _a_l.  It would be inappropriate to use a feature test macro
       to switch a macro definition of _g_e_t_c() between _g_e_t_c___l_o_c_k_e_d() and
       _g_e_t_c___u_n_l_o_c_k_e_d(), since the ISO C standard requires an actual function
       to exist, a function whose behavior could not be changed by the feature
       test macro. Also, providing both the _x_x_x___l_o_c_k_e_d() and _x_x_x___u_n_l_o_c_k_e_d()
       forms leads to the confusion of whether the suffix describes the
       behavior of the function or the circumstances under which it should be
       used.

       Three additional routines, _f_l_o_c_k_f_i_l_e(), _f_t_r_y_l_o_c_k_f_i_l_e(), and
       _f_u_n_l_o_c_k_f_i_l_e() (which may be macros), are provided to allow the user to
       delineate a sequence of I/O statements that are executed synchronously.

       The _u_n_g_e_t_c() function is infrequently called relative to the other
       functions/macros so no unlocked variation is needed.

FFUUTTUURREE DDIIRREECCTTIIOONNSS
       None.

SSEEEE AALLSSOO
       _S_e_c_t_i_o_n _2_._5, _S_t_a_n_d_a_r_d _I_/_O _S_t_r_e_a_m_s, _f_l_o_c_k_f_i_l_e(), _g_e_t_c(), _g_e_t_c_h_a_r(),
       _p_u_t_c(), _p_u_t_c_h_a_r()

       The Base Definitions volume of POSIX.1-2008, <<ssttddiioo..hh>>

CCOOPPYYRRIIGGHHTT
       Portions of this text are reprinted and reproduced in electronic form
       from IEEE Std 1003.1, 2013 Edition, Standard for Information Technology
       -- Portable Operating System Interface (POSIX), The Open Group Base
       Specifications Issue 7, Copyright (C) 2013 by the Institute of
       Electrical and Electronics Engineers, Inc and The Open Group.  (This is
       POSIX.1-2008 with the 2013 Technical Corrigendum 1 applied.) In the
       event of any discrepancy between this version and the original IEEE and
       The Open Group Standard, the original IEEE and The Open Group Standard
       is the referee document. The original Standard can be obtained online
       at http://www.unix.org/online.html .

       Any typographical or formatting errors that appear in this page are
       most likely to have been introduced during the conversion of the source
       files to man page format. To report such errors, see
       https://www.kernel.org/doc/man-pages/reporting_bugs.html .



IEEE/The Open Group                  2013                     GETC_UNLOCKED(3)
