/*
* malloc is thread safe, talloc is not
*/
- buffer = malloc(sizeof(char) * (FR_STRERROR_BUFSIZE + 1)); /* One byte extra for status */
+ buffer = calloc((FR_STRERROR_BUFSIZE * 2) + 1, sizeof(char)); /* One byte extra for status */
if (!buffer) {
fr_perror("Failed allocating memory for libradius error buffer");
return;
* NULL has a special meaning, setting the new byte to false.
*/
if (!fmt) {
- buffer[FR_STRERROR_BUFSIZE] = '\0';
+ buffer[FR_STRERROR_BUFSIZE * 2] = '\0';
return;
}
va_start(ap, fmt);
- vsnprintf(buffer, FR_STRERROR_BUFSIZE, fmt, ap);
- buffer[FR_STRERROR_BUFSIZE] = '\1'; /* Flip the 'new' byte to true */
+ /*
+ * Alternate where we write the message, so we can do:
+ * fr_strerror_printf("Additional error: %s", fr_strerror());
+ */
+ switch (buffer[FR_STRERROR_BUFSIZE * 2]) {
+ default:
+ vsnprintf(buffer + FR_STRERROR_BUFSIZE, FR_STRERROR_BUFSIZE, fmt, ap);
+ buffer[FR_STRERROR_BUFSIZE * 2] = '\2'; /* Flip the 'new' byte to true */
+ break;
+
+ case '\2':
+ vsnprintf(buffer, FR_STRERROR_BUFSIZE, fmt, ap);
+ buffer[FR_STRERROR_BUFSIZE * 2] = '\1'; /* Flip the 'new' byte to true */
+ break;
+ }
va_end(ap);
}
char *buffer;
buffer = fr_thread_local_get(fr_strerror_buffer);
- if (buffer && (buffer[FR_STRERROR_BUFSIZE] != '\0')) {
- buffer[FR_STRERROR_BUFSIZE] = '\0'; /* Flip the 'new' byte to false */
+ if (!buffer) return "";
+
+ switch (buffer[FR_STRERROR_BUFSIZE * 2]) {
+ default:
+ return "";
+
+ case '\1':
+ buffer[FR_STRERROR_BUFSIZE * 2] = '\0'; /* Flip the 'new' byte to false */
return buffer;
- }
- return "";
+ case '\2':
+ buffer[FR_STRERROR_BUFSIZE * 2] = '\0'; /* Flip the 'new' byte to false */
+ return buffer + FR_STRERROR_BUFSIZE;
+ }
}
/** Guaranteed to be thread-safe version of strerror