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 fully thread-safe
       manner. They shall be thread-safe when 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 can
       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:


           #undef getc_unlocked
           #undef putc_unlocked

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:


           flockfile(fileptr);
           putc_unlocked('1', fileptr);
           putc_unlocked('\n', fileptr);
           fprintf(fileptr, "Line 2\n");
           funlockfile(fileptr);

       is permissible, and results in the text sequence:


           1
           Line 2

       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-2017, <<ssttddiioo..hh>>

CCOOPPYYRRIIGGHHTT
       Portions of this text are reprinted and reproduced in electronic form
       from IEEE Std 1003.1-2017, Standard for Information Technology --
       Portable Operating System Interface (POSIX), The Open Group Base
       Specifications Issue 7, 2018 Edition, Copyright (C) 2018 by the
       Institute of Electrical and Electronics Engineers, Inc and The Open
       Group.  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.opengroup.org/unix/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                  2017                     GETC_UNLOCKED(3)
