GNU strerror_r 缓冲区含义

GNU strerror_r buffer meaning

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

这些 buf/buflen 参数有什么用?

空缓冲区非常有用:

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

此外,此缓冲区看起来未使用:

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

引用 man page强调我的

The GNU-specific strerror_r() returns a pointer to a string containing the error message. This may be either a pointer to a string that the function stores in buf, or a pointer to some (immutable) static string (in which case buf is unused).

所以很可能 buf 未使用,如果 buf 未使用,则 buflen 无关紧要。

[....] If the function stores a string in buf, then at most buflen bytes are stored (the string may be truncated if buflen is too small and errnum is unknown). [...]

正如您在评论中注意到的,bufbuflen 参数仅在您传递无效 errnum,负数或未知 errno 值。 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]);
}

关于缓冲区的容量,我认为1024字节就足够了。此外,它与 strerror 实现使用的大小完全相同(这是线程不安全的)。另见 the related answer and the comment to it

当然,这都是GNU版本的功能问题。 XSI 兼容版本始终使用此缓冲区来复制静态字符串。