Why is 'sys_errlist' deprecated in glibc?
Asked Answered
M

2

6

sys_errlist is a handy array which allows getting static errno descriptions. The alternative to it is the strerror_r function, which is available in two confusing incompatible flavors. The GNU version of it returns char *, which would be from that same aforementioned array as long as the error is known, or otherwise from the user-supplied buffer. The standards-compliant version of strerror_r returns an int instead, and always uses the user-supplied buffer. The problem is, those two functions share the same name despite having completely different semantics, so you basically have to perform a fairly complex #ifdef check and write two completely different versions of your code depending on which version you get. In addition to that, both of those functions are worse than sys_errlist, as both require for the caller to provide a "large enough" buffer to hold the description, even though the GNU version would rarely use it, and neither function allows to know just how large the buffer should really be. If instead you choose to use sys_errlist instead, you can simply check whether value >= sys_nerr and allocate the buffer only in that case, just to put the Unknown error %d there via snprintf, and be done.

Given that strerror_r is a horrible, incomprehensible and inefficient mess, why did GNU developers mark sys_errlist as deprecated, effectively forcing one to either use strerrror_r or to observe the ugly warning each time the code is compiled?

Morpho answered 26/11, 2015 at 23:43 Comment(0)
P
3

strerror and its relative are localized. The usefulness of a non-localized system message can be debated, but glibc's maintainers went with the prevailing direction (Solaris and other systems).

However: sys_errlist has been deprecated for quite a while. It is not a POSIX interface. Some systems do not have it.

Further reading:

It's been a while since this was an issue, but it used to be the case that some systems did not have strerror (see Unix Incompatibility Notes: String and Memory Functions).

Patriarchate answered 27/11, 2015 at 0:43 Comment(8)
This doesn't actually answer the question at all. sys_errlist is a static array and is completely thread safe.Yulan
There are a lot of non-standard things in glibc the usage of which doesn't seem to be accompanied with compile-time deprecation warningsMorpho
There are a ton of interfaces provided by Glibc that aren't POSIX-compliant, and aren't deprecated.Yulan
But there's nothing that isn't thread-safe about using sys_errlis.Yulan
What's funny that even now a number of builds doesn't support "new way" even while compiler nags about "old way"Deprecate
and apparently strerror is not thread-safe/reentrant (more, it's broken after fork)Deprecate
That (non-reentrant) is a consequence of it being localized. You might be able to tame it using POSIX locale. For fork - perhaps you're seeing problems with a vfork.Patriarchate
@ThomasDickey late andwer but I had other priorities. I'm not using fork directly . It's var use via Qt. On my production systems strerror is still not async-safe and projects literally have to implement their own sys_errlist analog before starting to function. Which leads to possibility of some mistakes.Deprecate
D
0

Pretty much the only viable solution if you have problem with strerror is not use it at run-time outside of initialization stage.

  • Use complex platform check to determine what's available.
  • Use conditional compilation to select proper interface.
  • If static list not available, the program should at copy strerror to your own static storage at beginning of work. There is a brief moment where these are not available during initialization.

E.g. nginx did it this way: https://trac.nginx.org/nginx/browser/nginx/src/os/unix/ngx_errno.c

Deprecate answered 15/7, 2024 at 11:42 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.