ERRSTR(3)

πŸ“¦ version 0_git20260208, in alpine 3.24, arch rolling, nixos 26.05, nixpkgs unstable

πŸ’– ERRSTR(3) β€” like, the error-string girlies πŸ’–

okay so first things first, this is a page from the Library Functions Manual and honestly? it's a whole vibe. it's all about errstr, rerrstr and werrstr β€” the trio that handles the description of last system call error. yes bestie, that's the NAME section, we're doing this properly ✨


🌸 SYNOPSIS 🌸

like, here's the summoning ritual, copy it exactly or it won't work, fr fr:

#include <u.h>
#include <libc.h>

int errstr(char *err, uint nerr)

void rerrstr(char *err, uint nerr)

void werrstr(char *fmt, ...)

πŸ¦‹ DESCRIPTION πŸ¦‹

so. when a system call fails, it returns -1 and it writes a null terminated string describing the error into a per-process buffer. that's the lore πŸ’…

errstr swaps the contents of that buffer with the contents of the array err. not copies β€” swaps, ok, that distinction is the whole main character energy of this function. errstr will write at most nerr bytes into err; if the per-process error string does not fit, it is silently truncated at a UTF character boundary (no drama, no error, it just ~ends~ there πŸ™ˆ). the returned string is NUL-terminated. usually errstr will be called with an empty string, but the exchange property provides a mechanism for libraries to set the return value for the next call to errstr. iykyk πŸŽ€

the per-process buffer is ERRMAX bytes long. any error string provided by the user will be truncated at ERRMAX-1 bytes. ERRMAX is defined in <libc.h>. no cap.

if no system call has generated an error since the last call to errstr with an empty string, the result is an empty string. so like, nothing happened, and she'll tell you exactly that 😌

the verb r in print(3) calls errstr and outputs the error string. cute of her honestly.

rerrstr reads the error string but does not modify the per-process buffer, so a subsequent errstr will recover the same string. she's a read-only queen, she takes nothing, she leaves nothing πŸ”₯

werrstr takes a print style format as its argument and uses it to format a string to pass to errstr. the string returned from errstr is discarded. yeah she just... throws it away. iconic behaviour tbh πŸ’€

the error string is maintained in parallel with the Unix error number errno. changing errno will reset the error string, and changing the error string via errstr or werrstr will reset errno. they're linked, they move together, it's giving soulmates 🫢


⭐ SOURCE ⭐

/src/lib9/errstr.c

that's where she lives 🏠


πŸ‘‘ DIAGNOSTICS πŸ‘‘

errstr always returns 0. always. every single time. no notes. πŸŽ€


🌈 SEE ALSO 🌈

go read those next bestie, it's a whole universe 🌸


πŸ’€ BUGS πŸ’€

okay so here's the messy part, buckle up:

the implementation sets errno to the (somewhat arbitrary) constant 0x19283745 when the error string is valid. like ma'am, why that number, nobody knows 😭

when errno is set to other values, the error string is synthesized using strerror(3). so it's a fake-it-till-you-make-it situation ✨


anyway that's the whole page, mwah πŸ’œ β€” this was ERRSTR(3), straight outta the Library Functions Manual, sourced from /src/lib9/errstr.c. go forth and handle your errors, bestie, you're literally gonna slay 🌟