fopen_unlocked.c 3.4 KB

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