1*38fd1498Szrj /* Implement fopen_unlocked and related functions.
2*38fd1498Szrj Copyright (C) 2005-2018 Free Software Foundation, Inc.
3*38fd1498Szrj Written by Kaveh R. Ghazi <ghazi@caip.rutgers.edu>.
4*38fd1498Szrj
5*38fd1498Szrj This file is part of the libiberty library.
6*38fd1498Szrj Libiberty is free software; you can redistribute it and/or
7*38fd1498Szrj modify it under the terms of the GNU Library General Public
8*38fd1498Szrj License as published by the Free Software Foundation; either
9*38fd1498Szrj version 2 of the License, or (at your option) any later version.
10*38fd1498Szrj
11*38fd1498Szrj Libiberty is distributed in the hope that it will be useful,
12*38fd1498Szrj but WITHOUT ANY WARRANTY; without even the implied warranty of
13*38fd1498Szrj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14*38fd1498Szrj Library General Public License for more details.
15*38fd1498Szrj
16*38fd1498Szrj You should have received a copy of the GNU Library General Public
17*38fd1498Szrj License along with libiberty; see the file COPYING.LIB. If
18*38fd1498Szrj not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
19*38fd1498Szrj Boston, MA 02110-1301, USA. */
20*38fd1498Szrj
21*38fd1498Szrj /*
22*38fd1498Szrj
23*38fd1498Szrj @deftypefn Extension void unlock_stream (FILE * @var{stream})
24*38fd1498Szrj
25*38fd1498Szrj If the OS supports it, ensure that the supplied stream is setup to
26*38fd1498Szrj avoid any multi-threaded locking. Otherwise leave the @code{FILE}
27*38fd1498Szrj pointer unchanged. If the @var{stream} is @code{NULL} do nothing.
28*38fd1498Szrj
29*38fd1498Szrj @end deftypefn
30*38fd1498Szrj
31*38fd1498Szrj @deftypefn Extension void unlock_std_streams (void)
32*38fd1498Szrj
33*38fd1498Szrj If the OS supports it, ensure that the standard I/O streams,
34*38fd1498Szrj @code{stdin}, @code{stdout} and @code{stderr} are setup to avoid any
35*38fd1498Szrj multi-threaded locking. Otherwise do nothing.
36*38fd1498Szrj
37*38fd1498Szrj @end deftypefn
38*38fd1498Szrj
39*38fd1498Szrj @deftypefn Extension {FILE *} fopen_unlocked (const char *@var{path}, @
40*38fd1498Szrj const char * @var{mode})
41*38fd1498Szrj
42*38fd1498Szrj Opens and returns a @code{FILE} pointer via @code{fopen}. If the
43*38fd1498Szrj operating system supports it, ensure that the stream is setup to avoid
44*38fd1498Szrj any multi-threaded locking. Otherwise return the @code{FILE} pointer
45*38fd1498Szrj unchanged.
46*38fd1498Szrj
47*38fd1498Szrj @end deftypefn
48*38fd1498Szrj
49*38fd1498Szrj @deftypefn Extension {FILE *} fdopen_unlocked (int @var{fildes}, @
50*38fd1498Szrj const char * @var{mode})
51*38fd1498Szrj
52*38fd1498Szrj Opens and returns a @code{FILE} pointer via @code{fdopen}. If the
53*38fd1498Szrj operating system supports it, ensure that the stream is setup to avoid
54*38fd1498Szrj any multi-threaded locking. Otherwise return the @code{FILE} pointer
55*38fd1498Szrj unchanged.
56*38fd1498Szrj
57*38fd1498Szrj @end deftypefn
58*38fd1498Szrj
59*38fd1498Szrj @deftypefn Extension {FILE *} freopen_unlocked (const char * @var{path}, @
60*38fd1498Szrj const char * @var{mode}, FILE * @var{stream})
61*38fd1498Szrj
62*38fd1498Szrj Opens and returns a @code{FILE} pointer via @code{freopen}. If the
63*38fd1498Szrj operating system supports it, ensure that the stream is setup to avoid
64*38fd1498Szrj any multi-threaded locking. Otherwise return the @code{FILE} pointer
65*38fd1498Szrj unchanged.
66*38fd1498Szrj
67*38fd1498Szrj @end deftypefn
68*38fd1498Szrj
69*38fd1498Szrj */
70*38fd1498Szrj
71*38fd1498Szrj #ifdef HAVE_CONFIG_H
72*38fd1498Szrj #include "config.h"
73*38fd1498Szrj #endif
74*38fd1498Szrj #include <stdio.h>
75*38fd1498Szrj #ifdef HAVE_STDIO_EXT_H
76*38fd1498Szrj #include <stdio_ext.h>
77*38fd1498Szrj #endif
78*38fd1498Szrj
79*38fd1498Szrj #include "libiberty.h"
80*38fd1498Szrj
81*38fd1498Szrj /* This is an inline helper function to consolidate attempts to unlock
82*38fd1498Szrj a stream. */
83*38fd1498Szrj
84*38fd1498Szrj static inline void
unlock_1(FILE * const fp ATTRIBUTE_UNUSED)85*38fd1498Szrj unlock_1 (FILE *const fp ATTRIBUTE_UNUSED)
86*38fd1498Szrj {
87*38fd1498Szrj #if defined(HAVE___FSETLOCKING) && defined(FSETLOCKING_BYCALLER)
88*38fd1498Szrj if (fp)
89*38fd1498Szrj __fsetlocking (fp, FSETLOCKING_BYCALLER);
90*38fd1498Szrj #endif
91*38fd1498Szrj }
92*38fd1498Szrj
93*38fd1498Szrj void
unlock_stream(FILE * fp)94*38fd1498Szrj unlock_stream (FILE *fp)
95*38fd1498Szrj {
96*38fd1498Szrj unlock_1 (fp);
97*38fd1498Szrj }
98*38fd1498Szrj
99*38fd1498Szrj void
unlock_std_streams(void)100*38fd1498Szrj unlock_std_streams (void)
101*38fd1498Szrj {
102*38fd1498Szrj unlock_1 (stdin);
103*38fd1498Szrj unlock_1 (stdout);
104*38fd1498Szrj unlock_1 (stderr);
105*38fd1498Szrj }
106*38fd1498Szrj
107*38fd1498Szrj FILE *
fopen_unlocked(const char * path,const char * mode)108*38fd1498Szrj fopen_unlocked (const char *path, const char *mode)
109*38fd1498Szrj {
110*38fd1498Szrj FILE *const fp = fopen (path, mode);
111*38fd1498Szrj unlock_1 (fp);
112*38fd1498Szrj return fp;
113*38fd1498Szrj }
114*38fd1498Szrj
115*38fd1498Szrj FILE *
fdopen_unlocked(int fildes,const char * mode)116*38fd1498Szrj fdopen_unlocked (int fildes, const char *mode)
117*38fd1498Szrj {
118*38fd1498Szrj FILE *const fp = fdopen (fildes, mode);
119*38fd1498Szrj unlock_1 (fp);
120*38fd1498Szrj return fp;
121*38fd1498Szrj }
122*38fd1498Szrj
123*38fd1498Szrj FILE *
freopen_unlocked(const char * path,const char * mode,FILE * stream)124*38fd1498Szrj freopen_unlocked (const char *path, const char *mode, FILE *stream)
125*38fd1498Szrj {
126*38fd1498Szrj FILE *const fp = freopen (path, mode, stream);
127*38fd1498Szrj unlock_1 (fp);
128*38fd1498Szrj return fp;
129*38fd1498Szrj }
130