blob: 9d270c0e47031508f352bac5532052716bcf3131 [file] [log] [blame]
John Park33858a32018-09-28 23:05:48 -07001#include "aos/libc/aos_strerror.h"
Brian Silverman01be0002014-05-10 15:44:38 -07002
Brian Silvermanb47f5552020-10-01 15:08:14 -07003#include <sys/types.h>
4
Tyler Chatowbf0609c2021-07-31 16:13:27 -07005#include <cassert>
6#include <cstdio>
7#include <cstring>
8
Brian Silverman01be0002014-05-10 15:44:38 -07009// This code uses an overloaded function to handle the result from either
10// version of strerror_r correctly without needing a way to get the choice out
11// of the compiler/glibc/whatever explicitly.
12
13namespace {
14
15const size_t kBufferSize = 128;
16
17// Handle the result from the GNU version of strerror_r. It never fails, so
18// that's pretty easy...
Brian Silvermanb47f5552020-10-01 15:08:14 -070019__attribute__((unused)) char *aos_strerror_handle_result(int /*error*/,
20 char *ret,
21 char * /*buffer*/) {
Brian Silverman01be0002014-05-10 15:44:38 -070022 return ret;
23}
24
25// Handle the result from the POSIX version of strerror_r.
Brian Silvermanb47f5552020-10-01 15:08:14 -070026__attribute__((unused)) char *aos_strerror_handle_result(int error, int ret,
27 char *buffer) {
Brian Silverman01be0002014-05-10 15:44:38 -070028 if (ret != 0) {
Austin Schuh7a41be62015-10-31 13:06:55 -070029#ifndef NDEBUG
30 // assert doesn't use the return value when building optimized.
31 const int r =
32#endif
33 snprintf(buffer, kBufferSize, "Unknown error %d", error);
Brian Silvermanfe457de2014-05-26 22:04:08 -070034 assert(r > 0);
Brian Silverman01be0002014-05-10 15:44:38 -070035 }
36 return buffer;
37}
38
39} // namespace
40
Brian Silvermanaf784862014-05-13 08:14:55 -070041const char *aos_strerror(int error) {
Austin Schuhf7bfb652023-08-25 14:22:50 -070042 thread_local char buffer[kBufferSize];
Brian Silverman01be0002014-05-10 15:44:38 -070043
44 // Call the overload for whichever version we're using.
45 return aos_strerror_handle_result(
46 error, strerror_r(error, buffer, sizeof(buffer)), buffer);
47}