Search code examples
cglibcstrerror

GNU strerror_r buffer meaning


char *strerror_r(int errnum, char *buf, size_t buflen);

What are these buf/buflen parameters for?

Empty buffer works like a charm:

char* buf = nullptr;
fprintf(stderr, strerror_r(errno, buf, 0));

Also this buffer looks like unused:

char buf[1024];
fprintf(stderr, "%s\n", strerror_r(errno, buf, sizeof buf)); // Correct message here
fprintf(stderr, "%s\n", buf); // Empty

Solution

  • As you noticed in comments, buf and buflen parameters is used only if you pass invalid errnum, negative or unknown errno value. This is confirmed by the source code of the function.

    char *
    __strerror_r (int errnum, char *buf, size_t buflen)
    {
      if (__builtin_expect (errnum < 0 || errnum >= _sys_nerr_internal
                            || _sys_errlist_internal[errnum] == NULL, 0))
        {
          /* To fill up buf with "Unknown error" localized string and to append
             digits of errnum. Nothing happens if buflen equals zero. */
    
          ...
    
          return buf;
        }
    
      return (char *) _(_sys_errlist_internal[errnum]);
    }
    

    In relation capacity of the buffer, I think 1024 bytes will be enough. Moreover, it's the exact same size which strerror implementation uses (that's thread unsafe). See also the related answer and the comment to it.

    Of course, it all is concern of GNU-version of the function. XSI-compliant version always uses this buffer for copy of a static string.