1*4882a593Smuzhiyun // SPDX-License-Identifier: LGPL-2.1
2*4882a593Smuzhiyun #undef _GNU_SOURCE
3*4882a593Smuzhiyun #include <string.h>
4*4882a593Smuzhiyun #include <stdio.h>
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun #include "event-parse.h"
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #undef _PE
9*4882a593Smuzhiyun #define _PE(code, str) str
10*4882a593Smuzhiyun static const char * const tep_error_str[] = {
11*4882a593Smuzhiyun TEP_ERRORS
12*4882a593Smuzhiyun };
13*4882a593Smuzhiyun #undef _PE
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun /*
16*4882a593Smuzhiyun * The tools so far have been using the strerror_r() GNU variant, that returns
17*4882a593Smuzhiyun * a string, be it the buffer passed or something else.
18*4882a593Smuzhiyun *
19*4882a593Smuzhiyun * But that, besides being tricky in cases where we expect that the function
20*4882a593Smuzhiyun * using strerror_r() returns the error formatted in a provided buffer (we have
21*4882a593Smuzhiyun * to check if it returned something else and copy that instead), breaks the
22*4882a593Smuzhiyun * build on systems not using glibc, like Alpine Linux, where musl libc is
23*4882a593Smuzhiyun * used.
24*4882a593Smuzhiyun *
25*4882a593Smuzhiyun * So, introduce yet another wrapper, str_error_r(), that has the GNU
26*4882a593Smuzhiyun * interface, but uses the portable XSI variant of strerror_r(), so that users
27*4882a593Smuzhiyun * rest asured that the provided buffer is used and it is what is returned.
28*4882a593Smuzhiyun */
tep_strerror(struct tep_handle * tep __maybe_unused,enum tep_errno errnum,char * buf,size_t buflen)29*4882a593Smuzhiyun int tep_strerror(struct tep_handle *tep __maybe_unused,
30*4882a593Smuzhiyun enum tep_errno errnum, char *buf, size_t buflen)
31*4882a593Smuzhiyun {
32*4882a593Smuzhiyun const char *msg;
33*4882a593Smuzhiyun int idx;
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun if (!buflen)
36*4882a593Smuzhiyun return 0;
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun if (errnum >= 0) {
39*4882a593Smuzhiyun int err = strerror_r(errnum, buf, buflen);
40*4882a593Smuzhiyun buf[buflen - 1] = 0;
41*4882a593Smuzhiyun return err;
42*4882a593Smuzhiyun }
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun if (errnum <= __TEP_ERRNO__START ||
45*4882a593Smuzhiyun errnum >= __TEP_ERRNO__END)
46*4882a593Smuzhiyun return -1;
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun idx = errnum - __TEP_ERRNO__START - 1;
49*4882a593Smuzhiyun msg = tep_error_str[idx];
50*4882a593Smuzhiyun snprintf(buf, buflen, "%s", msg);
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun return 0;
53*4882a593Smuzhiyun }
54