xref: /dflybsd-src/contrib/binutils-2.27/libiberty/fopen_unlocked.c (revision e656dc90e3d65d744d534af2f5ea88cf8101ebcf)
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