1169695Skan/* Implement fopen_unlocked and related functions.
2169695Skan   Copyright (C) 2005 Free Software Foundation, Inc.
3169695Skan   Written by Kaveh R. Ghazi <ghazi@caip.rutgers.edu>.
4169695Skan
5169695SkanThis file is part of the libiberty library.
6169695SkanLibiberty is free software; you can redistribute it and/or
7169695Skanmodify it under the terms of the GNU Library General Public
8169695SkanLicense as published by the Free Software Foundation; either
9169695Skanversion 2 of the License, or (at your option) any later version.
10169695Skan
11169695SkanLibiberty is distributed in the hope that it will be useful,
12169695Skanbut WITHOUT ANY WARRANTY; without even the implied warranty of
13169695SkanMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14169695SkanLibrary General Public License for more details.
15169695Skan
16169695SkanYou should have received a copy of the GNU Library General Public
17169695SkanLicense along with libiberty; see the file COPYING.LIB.  If
18169695Skannot, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
19169695SkanBoston, MA 02110-1301, USA.  */
20169695Skan
21169695Skan/*
22169695Skan
23169695Skan@deftypefn Extension void unlock_stream (FILE * @var{stream})
24169695Skan
25169695SkanIf the OS supports it, ensure that the supplied stream is setup to
26169695Skanavoid any multi-threaded locking.  Otherwise leave the @code{FILE}
27169695Skanpointer unchanged.  If the @var{stream} is @code{NULL} do nothing.
28169695Skan
29169695Skan@end deftypefn
30169695Skan
31169695Skan@deftypefn Extension void unlock_std_streams (void)
32169695Skan
33169695SkanIf the OS supports it, ensure that the standard I/O streams,
34169695Skan@code{stdin}, @code{stdout} and @code{stderr} are setup to avoid any
35169695Skanmulti-threaded locking.  Otherwise do nothing.
36169695Skan
37169695Skan@end deftypefn
38169695Skan
39169695Skan@deftypefn Extension {FILE *} fopen_unlocked (const char *@var{path}, const char * @var{mode})
40169695Skan
41169695SkanOpens and returns a @code{FILE} pointer via @code{fopen}.  If the
42169695Skanoperating system supports it, ensure that the stream is setup to avoid
43169695Skanany multi-threaded locking.  Otherwise return the @code{FILE} pointer
44169695Skanunchanged.
45169695Skan
46169695Skan@end deftypefn
47169695Skan
48169695Skan@deftypefn Extension {FILE *} fdopen_unlocked (int @var{fildes}, const char * @var{mode})
49169695Skan
50169695SkanOpens and returns a @code{FILE} pointer via @code{fdopen}.  If the
51169695Skanoperating system supports it, ensure that the stream is setup to avoid
52169695Skanany multi-threaded locking.  Otherwise return the @code{FILE} pointer
53169695Skanunchanged.
54169695Skan
55169695Skan@end deftypefn
56169695Skan
57169695Skan@deftypefn Extension {FILE *} freopen_unlocked (const char * @var{path}, const char * @var{mode}, FILE * @var{stream})
58169695Skan
59169695SkanOpens and returns a @code{FILE} pointer via @code{freopen}.  If the
60169695Skanoperating system supports it, ensure that the stream is setup to avoid
61169695Skanany multi-threaded locking.  Otherwise return the @code{FILE} pointer
62169695Skanunchanged.
63169695Skan
64169695Skan@end deftypefn
65169695Skan
66169695Skan*/
67169695Skan
68169695Skan#ifdef HAVE_CONFIG_H
69169695Skan#include "config.h"
70169695Skan#endif
71169695Skan#include <stdio.h>
72169695Skan#ifdef HAVE_STDIO_EXT_H
73169695Skan#include <stdio_ext.h>
74169695Skan#endif
75169695Skan
76169695Skan#include "libiberty.h"
77169695Skan
78169695Skan/* This is an inline helper function to consolidate attempts to unlock
79169695Skan   a stream.  */
80169695Skan
81169695Skanstatic inline void
82169695Skanunlock_1 (FILE *const fp ATTRIBUTE_UNUSED)
83169695Skan{
84169695Skan#if defined(HAVE___FSETLOCKING) && defined(FSETLOCKING_BYCALLER)
85169695Skan  if (fp)
86169695Skan    __fsetlocking (fp, FSETLOCKING_BYCALLER);
87169695Skan#endif
88169695Skan}
89169695Skan
90169695Skanvoid
91169695Skanunlock_stream (FILE *fp)
92169695Skan{
93169695Skan  unlock_1 (fp);
94169695Skan}
95169695Skan
96169695Skanvoid
97169695Skanunlock_std_streams (void)
98169695Skan{
99169695Skan  unlock_1 (stdin);
100169695Skan  unlock_1 (stdout);
101169695Skan  unlock_1 (stderr);
102169695Skan}
103169695Skan
104169695SkanFILE *
105169695Skanfopen_unlocked (const char *path, const char *mode)
106169695Skan{
107169695Skan  FILE *const fp = fopen (path, mode);
108169695Skan  unlock_1 (fp);
109169695Skan  return fp;
110169695Skan}
111169695Skan
112169695SkanFILE *
113169695Skanfdopen_unlocked (int fildes, const char *mode)
114169695Skan{
115169695Skan  FILE *const fp = fdopen (fildes, mode);
116169695Skan  unlock_1 (fp);
117169695Skan  return fp;
118169695Skan}
119169695Skan
120169695SkanFILE *
121169695Skanfreopen_unlocked (const char *path, const char *mode, FILE *stream)
122169695Skan{
123169695Skan  FILE *const fp = freopen (path, mode, stream);
124169695Skan  unlock_1 (fp);
125169695Skan  return fp;
126169695Skan}
127