The OpenGroup POSIX.1-2001 defines strerror_r, as does The Linux Standard Base Core Specification 3.1. But I can find no reference to the maximum size that could be reasonably expected for an error message. I expected some define somewhere that I could put in my code but there is none that I can find.
The code must be thread safe. Which is why strerror_r is used and not strerror.
Does any one know the symbol I can use? I should I create my own?
int result = gethostname(p_buffy, size_buffy);
int errsv = errno;
if (result < 0)
{
char buf[256];
char const * str = strerror_r(errsv, buf, 256);
syslog(LOG_ERR,
"gethostname failed; errno=%d(%s), buf='%s'",
errsv,
str,
p_buffy);
return errsv;
}
From the documents:
The Open Group Base Specifications Issue 6:
ERRORS
The strerror_r() function may fail if:
- [ERANGE] Insufficient storage was supplied via strerrbuf and buflen to contain the generated message string.
From the source:
glibc-2.7/glibc-2.7/string/strerror.c:41:
char *
strerror (errnum)
int errnum;
{
...
buf = malloc (1024);
Having a sufficiently large static limit is probably good enough for all situations. If you really need to get the entire error message, you can use the GNU version of strerror_r, or you can use the standard version and poll it with successively larger buffers until you get what you need. For example, you may use something like the code below.
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Call strerror_r and get the full error message. Allocate memory for the
* entire string with malloc. Return string. Caller must free string.
* If malloc fails, return NULL.
*/
char *all_strerror(int n)
{
char *s;
size_t size;
size = 1024;
s = malloc(size);
if (s == NULL)
return NULL;
while (strerror_r(n, s, size) == -1 && errno == ERANGE) {
size *= 2;
s = realloc(s, size);
if (s == NULL)
return NULL;
}
return s;
}
int main(int argc, char **argv)
{
for (int i = 1; i < argc; ++i) {
int n = atoi(argv[i]);
char *s = all_strerror(n);
printf("[%d]: %s\n", n, s);
free(s);
}
return 0;
}