(root)/
binutils-2.41/
libiberty/
fopen_unlocked.c
       1  /* Implement fopen_unlocked and related functions.
       2     Copyright (C) 2005-2023 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  }