generic_category_message.hpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #ifndef BOOST_SYSTEM_DETAIL_GENERIC_CATEGORY_MESSAGE_HPP_INCLUDED
  2. #define BOOST_SYSTEM_DETAIL_GENERIC_CATEGORY_MESSAGE_HPP_INCLUDED
  3. // Implementation of generic_error_category_message
  4. //
  5. // Copyright 2018 Peter Dimov
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. // See library home page at http://www.boost.org/libs/system
  11. #include <boost/config.hpp>
  12. #include <string>
  13. #include <cstring>
  14. namespace boost
  15. {
  16. namespace system
  17. {
  18. namespace detail
  19. {
  20. #if defined(__GLIBC__)
  21. // glibc has two incompatible strerror_r definitions
  22. inline char const * strerror_r_helper( char const * r, char const * ) noexcept
  23. {
  24. return r;
  25. }
  26. inline char const * strerror_r_helper( int r, char const * buffer ) noexcept
  27. {
  28. return r == 0? buffer: "Unknown error";
  29. }
  30. inline char const * generic_error_category_message( int ev, char * buffer, std::size_t len ) noexcept
  31. {
  32. if( buffer != nullptr )
  33. {
  34. return strerror_r_helper( strerror_r( ev, buffer, len ), buffer );
  35. }
  36. else
  37. {
  38. // strerror_r requires non-null buffer pointer
  39. char tmp[ 1 ] = {};
  40. char const* r = strerror_r_helper( strerror_r( ev, tmp, 0 ), buffer );
  41. return r == tmp? nullptr: r;
  42. }
  43. }
  44. inline std::string generic_error_category_message( int ev )
  45. {
  46. char buffer[ 128 ];
  47. return generic_error_category_message( ev, buffer, sizeof( buffer ) );
  48. }
  49. #else // #if defined(__GLIBC__)
  50. // std::strerror is thread-safe on everything else, incl. Windows
  51. # if defined( BOOST_MSVC )
  52. # pragma warning( push )
  53. # pragma warning( disable: 4996 )
  54. # elif defined(__clang__) && defined(__has_warning)
  55. # pragma clang diagnostic push
  56. # if __has_warning("-Wdeprecated-declarations")
  57. # pragma clang diagnostic ignored "-Wdeprecated-declarations"
  58. # endif
  59. # endif
  60. inline std::string generic_error_category_message( int ev )
  61. {
  62. char const * m = std::strerror( ev );
  63. return m? m: "Unknown error";
  64. }
  65. inline char const * generic_error_category_message( int ev, char * buffer, std::size_t len ) noexcept
  66. {
  67. if( len == 0 )
  68. {
  69. return buffer;
  70. }
  71. if( len == 1 )
  72. {
  73. buffer[0] = 0;
  74. return buffer;
  75. }
  76. char const * m = std::strerror( ev );
  77. if( m == 0 ) return "Unknown error";
  78. std::strncpy( buffer, m, len - 1 );
  79. buffer[ len-1 ] = 0;
  80. return buffer;
  81. }
  82. # if defined( BOOST_MSVC )
  83. # pragma warning( pop )
  84. # elif defined(__clang__) && defined(__has_warning)
  85. # pragma clang diagnostic pop
  86. # endif
  87. #endif // #if defined(__GLIBC__)
  88. } // namespace detail
  89. } // namespace system
  90. } // namespace boost
  91. #endif // #ifndef BOOST_SYSTEM_DETAIL_GENERIC_CATEGORY_MESSAGE_HPP_INCLUDED