errc(3bsd)
π errc, verrc, warnc, vwarnc β formatted error messages π
okay bestie, so this is errc(3bsd), a little page from the BSD corner of your system (it lives under LOCAL in the manual shelf, if you were wondering) and it's literally the "tell me what went wrong, but make it formatted" squad π«Ά
πΈ LIBRARY πΈ
Utility functions from BSD systems β that's libbsd, and you link it with -lbsd. β¨
β¨ SYNOPSIS β¨
#include <err.h>
(peep libbsd(7) for how the include situation actually works, iykyk)
void
errc(int status, int code, const char *fmt, ...);
void
verrc(int status, int code, const char *fmt, va_list args);
void
warnc(int code, const char *fmt, ...);
void
vwarnc(int code, const char *fmt, va_list args);
π DESCRIPTION π
So the err() and warn() family of functions print a formatted error message out on standard error output. Every single one of them, no exceptions. And in all cases, they start you off with the last component of the program name, then a colon (:) character, then a space. Iconic little intro, honestly. π
What comes after that depends on which function you called, bestie. The fmt specification β plus whatever arguments come with it β can be any format that printf(3) allows, or it can be NULL. If fmt is not NULL, then yeah, the formatted error message gets printed.
Now here's the tea: all of these functions also print an error message string that's affiliated with an error value (go look at strerror(3) if you want the lore on that one). That string gets preceded by a colon character and a space β but only if fmt is not NULL. So the output looks like this:
progname: fmt: error message string
when fmt is not NULL, or like this:
progname: error message string
when it is. π¦
The code argument is used as the error value instead of whatever the global variable errno is currently holding. Not me swapping out errno's whole moment. π
And in all cases, the output gets a newline character tacked on at the end. Periodt.
Oh, and heads up: errc() and verrc() do not return. They exit with the value of the status argument. They're not coming back, they said what they said. π
π EXAMPLES π
Display the current errno information string and exit:
if ((p = malloc(size)) == NULL)
err(1, NULL);
if ((fd = open(file_name, O_RDONLY, 0)) == -1)
err(1, "%s", file_name);
Display an error message and exit:
if (tm.tm_hour < START_TIME)
errx(1, "too early, wait until %s", start_time_string);
Warn of an error:
if ((fd = open(raw_device, O_RDONLY, 0)) == -1)
warnx("%s: %s: trying the block device",
raw_device, strerror(errno));
if ((fd = open(block_device, O_RDONLY, 0)) == -1)
err(1, "%s", block_device);
π SEE ALSO π
err(3) exit(3), perror(3), printf(3), strerror(3)
π HISTORY π
The functions errc(), verrc(), warnc(), and vwarnc() first appeared in FreeBSD 3.0, NetBSD 7.0 and OpenBSD 5.6. They've been around, they've got seniority. β
β οΈ CAVEATS β οΈ
bestie. listen. this part is not a vibe. this part is serious. π¨
It is important β like, never-ever β to pass a string with user-supplied data as a format without using %s. Why? Because an attacker can put format specifiers in that string and mangle the stack, which leads to a possible security hole. And this holds true even if the string has been built "by hand" using a function like snprintf(), because the resulting string may still contain user-supplied conversion specifiers that get interpolated later by the err() and warn() family of functions. So yes, the danger is still lurking in there. π
Always be sure to use the proper secure idiom:
errc(1, 0, "%s", string);
That's the one. That's the safe one. Use that one. π
and that's the whole page, bestie!! this one shipped with Debian, dated April 23, 2014 β go forth and format your errors securely, mwah π β¨
π¦ where this page comes from
- alpine 3.22: libbsd-doc 0.12.2-r0 Β· BSD-3-Clause
- alpine 3.23: libbsd-doc 0.12.2-r0 Β· BSD-3-Clause
- alpine 3.24: libbsd-doc 0.12.2-r0 Β· BSD-3-Clause
- arch rolling: libbsd 0.12.2-2 Β· custom
- debian bookworm: libbsd-dev 0.11.7-2
- debian trixie: libbsd-dev 0.12.2-2
- epel 10: libbsd-devel 0.12.2-4.el10_0 Β· Beerware AND BSD-2-Clause AND BSD-3-Clause AND ISC AND libutil-David-Nugent AND MIT AND LicenseRef-Fedora-Public-Domain
- epel 9: libbsd-devel 0.12.2-1.el9 Β· Beerware AND BSD-2-Clause AND BSD-3-Clause AND ISC AND libutil-David-Nugent AND MIT AND LicenseRef-Fedora-Public-Domain
- fedora 43: libbsd-devel 0.12.2-6.fc43 Β· Beerware AND BSD-2-Clause AND BSD-3-Clause AND ISC AND libutil-David-Nugent AND MIT AND LicenseRef-Fedora-Public-Domain
- fedora 43: libbsd-devel 0.12.2-6.fc43 Β· Beerware AND BSD-2-Clause AND BSD-3-Clause AND ISC AND libutil-David-Nugent AND MIT AND LicenseRef-Fedora-Public-Domain
- fedora 44: libbsd-devel 0.12.2-7.fc44 Β· Beerware AND BSD-2-Clause AND BSD-3-Clause AND ISC AND libutil-David-Nugent AND MIT AND LicenseRef-Fedora-Public-Domain
- fedora 44: libbsd-devel 0.12.2-7.fc44 Β· Beerware AND BSD-2-Clause AND BSD-3-Clause AND ISC AND libutil-David-Nugent AND MIT AND LicenseRef-Fedora-Public-Domain
- nixos 26.05: libbsd 0.12.2
- opensuse-leap 16.0: libbsd-devel 0.11.7-160000.3.2 Β· BSD-3-Clause
- opensuse-leap 16.0: libbsd-devel 0.11.7-160000.3.2 Β· BSD-3-Clause
- opensuse-leap 16.0: libbsd-devel 0.11.7-160000.3.2 Β· BSD-3-Clause
- opensuse-leap 16.0: libbsd-devel 0.11.7-160000.3.2 Β· BSD-3-Clause
- ubuntu noble: libbsd-dev 0.12.1-1build1
- ubuntu noble: libbsd-dev 0.12.1-1build1.1
- ubuntu questing: libbsd-dev 0.12.2-2build1
- ubuntu resolute: libbsd-dev 0.12.2-2build2
- ubuntu stonking: libbsd-dev 0.12.2-3
- Copyright (c) 1993 The Regents of the University of California. All rights reserved
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms