Home | History | Annotate | Download | only in libiberty
      1 /* Implement fopen_unlocked and related functions.
      2    Copyright (C) 2005, 2011 Free Software Foundation, Inc.
      3    Written by Kaveh R. Ghazi <ghazi (at) 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