1 /* Implement fopen_unlocked and related functions. 2 Copyright (C) 2005-2020 Free Software Foundation, Inc. 3 Written by Kaveh R. Ghazi <ghazi@caip.rutgers.edu>. 4 5 This file is part of the libiberty library. 6 Libiberty is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Library General Public 8 License as published by the Free Software Foundation; either 9 version 2 of the License, or (at your option) any later version. 10 11 Libiberty is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Library General Public License for more details. 15 16 You should have received a copy of the GNU Library General Public 17 License along with libiberty; see the file COPYING.LIB. If 18 not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 19 Boston, MA 02110-1301, USA. */ 20 21 /* 22 23 @deftypefn Extension void unlock_stream (FILE * @var{stream}) 24 25 If the OS supports it, ensure that the supplied stream is setup to 26 avoid any multi-threaded locking. Otherwise leave the @code{FILE} 27 pointer unchanged. If the @var{stream} is @code{NULL} do nothing. 28 29 @end deftypefn 30 31 @deftypefn Extension void unlock_std_streams (void) 32 33 If the OS supports it, ensure that the standard I/O streams, 34 @code{stdin}, @code{stdout} and @code{stderr} are setup to avoid any 35 multi-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 42 Opens and returns a @code{FILE} pointer via @code{fopen}. If the 43 operating system supports it, ensure that the stream is setup to avoid 44 any multi-threaded locking. Otherwise return the @code{FILE} pointer 45 unchanged. 46 47 @end deftypefn 48 49 @deftypefn Extension {FILE *} fdopen_unlocked (int @var{fildes}, @ 50 const char * @var{mode}) 51 52 Opens and returns a @code{FILE} pointer via @code{fdopen}. If the 53 operating system supports it, ensure that the stream is setup to avoid 54 any multi-threaded locking. Otherwise return the @code{FILE} pointer 55 unchanged. 56 57 @end deftypefn 58 59 @deftypefn Extension {FILE *} freopen_unlocked (const char * @var{path}, @ 60 const char * @var{mode}, FILE * @var{stream}) 61 62 Opens and returns a @code{FILE} pointer via @code{freopen}. If the 63 operating system supports it, ensure that the stream is setup to avoid 64 any multi-threaded locking. Otherwise return the @code{FILE} pointer 65 unchanged. 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 84 static inline void 85 unlock_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 93 void 94 unlock_stream (FILE *fp) 95 { 96 unlock_1 (fp); 97 } 98 99 void 100 unlock_std_streams (void) 101 { 102 unlock_1 (stdin); 103 unlock_1 (stdout); 104 unlock_1 (stderr); 105 } 106 107 FILE * 108 fopen_unlocked (const char *path, const char *mode) 109 { 110 FILE *const fp = fopen (path, mode); 111 unlock_1 (fp); 112 return fp; 113 } 114 115 FILE * 116 fdopen_unlocked (int fildes, const char *mode) 117 { 118 FILE *const fp = fdopen (fildes, mode); 119 unlock_1 (fp); 120 return fp; 121 } 122 123 FILE * 124 freopen_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