Skip to content

Commit 1cd1202

Browse files
committed
Refactor StrError_R() and fix doxygen references.
- In StrError_R(): Assume the happy path where the buffer is sufficient to hold the error message, first, instead of preemptively filling the buffer with the fallback numerical code. We rely on the fallback behaviour only when the buffer has been deemed to be too small. - In StrError_R(): Properly handle negative return values from snprintf(), instead of casting it away without considering the possibility of the value being negative. - Doxygen: generation of documentation produced warnings due to linking against strerror_r(), a symbol that wasn't found by doxygen because string.h wasn't included in StrError_R.h used to generate doc output. Including it wasn't necessary, so the references were dropped and fixed-width text is used to refer to the function instead.
1 parent 17d917c commit 1cd1202

File tree

2 files changed

+24
-23
lines changed

2 files changed

+24
-23
lines changed

common/base/StrError_R.cpp

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -36,28 +36,29 @@ const int StrError_R_BufSize(1024);
3636

3737
std::string StrError_R(int errnum) {
3838
// Pre-allocate to prevent re-allocation.
39-
std::string out(StrError_R_BufSize, ' ');
40-
out.assign("errno = ");
41-
42-
// Buffer size here is digits10 + 3 to account for:
43-
// - Systems in which the int type cannot represent the full range of base 10
44-
// digits in the position of the most significant base 10 digit.
45-
// - Terminating NUL byte added by snprintf.
46-
// - 1 additional unit of storage just in case something absurd is used
47-
// on the host system (negative errno / zero-width int type, anyone? -
48-
// though this is meant to be impossible).
49-
char errs[std::numeric_limits<int>::digits10 + 3];
50-
if (static_cast<unsigned int>(snprintf(errs, sizeof(errs), "%d", errnum))
51-
>= sizeof(errs)) {
52-
out.append("<truncated>");
53-
} else {
54-
out.append(errs);
55-
}
56-
const std::string::size_type olen(out.size());
57-
58-
out.resize(StrError_R_BufSize, ' ');
39+
std::string out(StrError_R_BufSize, '\0');
5940
if (StrError_R_XSI(errnum, &(out[0]), out.size())) {
60-
out.resize(olen);
41+
out.assign("errno = ");
42+
// Buffer size here is digits10 + 3 to account for:
43+
// - Systems in which the int type cannot represent the full range
44+
// of digits in the position of the most significant base 10 digit.
45+
// (i.e. 0-2 representable in an 8-bit unsigned integer at the
46+
// hundredth's place instead of 0-9 because an u8 is clamped to
47+
// [0, 255])
48+
// - Terminating NUL byte added by snprintf.
49+
// - 1 additional unit of storage just in case a negative errnum is
50+
// passed, and somehow StrError_R_XSI() failed on that.
51+
char errs[std::numeric_limits<int>::digits10 + 3];
52+
int r(snprintf(errs, sizeof(errs), "%d", errnum));
53+
if (r < 0) {
54+
out.append("<error>");
55+
// Ugly cast required to avoid compiler warning when comparing
56+
// numbers of different signedness.
57+
} else if (static_cast<unsigned int>(r) >= sizeof(errs)) {
58+
out.append("<truncated>");
59+
} else {
60+
out.append(errs);
61+
}
6162
} else {
6263
out.resize(strlen(&(out[0])));
6364
}

include/ola/base/StrError_R.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
* @defgroup strerror Description of system error codes
2424
* @brief Error descriptions
2525
* @details Convenience functions to obtain descriptions of system error codes.
26-
* The functions in this group are only defined if @ref strerror_r() is available.
26+
* The functions in this group are only defined if \c strerror_r() is available.
2727
*/
2828

2929
/**
@@ -55,7 +55,7 @@ namespace ola {
5555
extern const int StrError_R_BufSize;
5656

5757
/**
58-
* @brief XSI-compliant version of @ref strerror_r()
58+
* @brief XSI-compliant version of \c strerror_r()
5959
*
6060
* See https://linux.die.net/man/3/strerror for more details.
6161
*/

0 commit comments

Comments
 (0)