generic_category.hpp 2.1 KB

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