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