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