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