blob: c91fd00c33953557bd39287c3d15c762337c31d6 [file] [log] [blame]
Brian Silvermanaf784862014-05-13 08:14:55 -07001#include "aos/common/libc/aos_strerror.h"
Brian Silverman01be0002014-05-10 15:44:38 -07002
3#include <assert.h>
4#include <sys/types.h>
5#include <string.h>
6#include <stdio.h>
7
Brian Silverman01be0002014-05-10 15:44:38 -07008// This code uses an overloaded function to handle the result from either
9// version of strerror_r correctly without needing a way to get the choice out
10// of the compiler/glibc/whatever explicitly.
11
12namespace {
13
14const size_t kBufferSize = 128;
15
16// Handle the result from the GNU version of strerror_r. It never fails, so
17// that's pretty easy...
18__attribute__((unused))
19char *aos_strerror_handle_result(int /*error*/, char *ret, char * /*buffer*/) {
20 return ret;
21}
22
23// Handle the result from the POSIX version of strerror_r.
24__attribute__((unused))
25char *aos_strerror_handle_result(int error, int ret, char *buffer) {
26 if (ret != 0) {
Austin Schuh7a41be62015-10-31 13:06:55 -070027#ifndef NDEBUG
28 // assert doesn't use the return value when building optimized.
29 const int r =
30#endif
31 snprintf(buffer, kBufferSize, "Unknown error %d", error);
Brian Silvermanfe457de2014-05-26 22:04:08 -070032 assert(r > 0);
Brian Silverman01be0002014-05-10 15:44:38 -070033 }
34 return buffer;
35}
36
37} // namespace
38
Brian Silvermanaf784862014-05-13 08:14:55 -070039const char *aos_strerror(int error) {
Brian Silverman8f373b12015-04-03 15:36:52 -040040 static thread_local char buffer[kBufferSize];
Brian Silverman01be0002014-05-10 15:44:38 -070041
42 // Call the overload for whichever version we're using.
43 return aos_strerror_handle_result(
44 error, strerror_r(error, buffer, sizeof(buffer)), buffer);
45}