sys_errlist
是一个方便的数组,可以获取静态 errno
描述。它的替代方案是 strerror_r
函数,它有两种令人困惑的不兼容的风格。它的 GNU 版本返回 char *
,只要错误已知,它就会来自上述相同的数组,否则来自用户提供的缓冲区。符合标准的 strerror_r
版本会返回 int
,并且始终使用用户提供的缓冲区。问题是,这两个函数尽管具有完全不同的语义,但共享相同的名称,因此您基本上必须执行相当复杂的#ifdef
检查并根据您获得的版本编写两个完全不同的代码版本。除此之外,这两个函数都比 sys_errlist
更糟糕,因为它们都要求调用者提供一个“足够大”的缓冲区来保存描述,即使 GNU 版本很少使用它,并且两个函数都不允许知道缓冲区到底应该有多大。如果您选择使用 sys_errlist
代替,您可以简单地检查是否 value >= sys_nerr
并仅在这种情况下分配缓冲区,只需通过 Unknown error %d
将 snprintf
放在那里,然后完成。
鉴于
strerror_r
是一个可怕的、难以理解且低效的混乱,为什么 GNU 开发人员将 sys_errlist
标记为已弃用,实际上迫使人们要么使用 strerrror_r
要么在每次编译代码时观察丑陋的警告?
strerror
及其亲戚是本地化的。 非本地化系统消息的有用性可能存在争议,但 glibc 的维护者遵循了主流方向(Solaris 和其他系统)。
但是:
sys_errlist
已被弃用很长一段时间了。它不是 POSIX 接口。 有些系统没有它。
进一步阅读:
这个问题已经有一段时间了,但以前的情况是某些系统没有
strerror
(请参阅 Unix 不兼容说明:
字符串和内存函数)。
如果您遇到
strerror
问题,几乎唯一可行的解决方案是不在初始化阶段之外的运行时使用它。
strerror
复制到您自己的静态存储中。在初始化期间,有一个短暂的时刻这些不可用。例如nginx 是这样做的:https://trac.nginx.org/nginx/browser/nginx/src/os/unix/ngx_errno.c