ERR(3)
๐ ERR(3) โ ok so this is the error message glow-up page โจ
bestie, this is ERR(3) from the Library Functions Manual in libc, and it's literally the group chat of C error handling. two families: err (the dramatic ones that dip out) and warn (the side-eye ones that stick around). let's get into it ๐ซถ
โจ NAME โจ
so the whole squad is: err, verr, errc, verrc, errx, verrx, warn, vwarn, warnc, vwarnc, warnx, vwarnx, plus the setup girlies err_set_exit and err_set_file โ all about formatted error messages ๐
๐ LIBRARY ๐
the Standard C Library โ that's libc, linked with -lc. slay ๐ฆ
๐ธ SYNOPSIS ๐ธ
okay so first things first, you gotta include the header:
#include <err.h>
then the main character functions, in order, periodt:
void
err(int eval, const char *fmt, ...);
void
err_set_exit(void (*exitf)(int));
void
err_set_file(void *vfp);
void
errc(int eval, int code, const char *fmt, ...);
void
errx(int eval, const char *fmt, ...);
void
warn(const char *fmt, ...);
void
warnc(int code, const char *fmt, ...);
void
warnx(const char *fmt, ...);
then for the v-flavored ones, you need another header, no cap:
#include <stdarg.h>
and here's the rest of the lineup:
void
verr(int eval, const char *fmt, va_list args);
void
verrc(int eval, int code, const char *fmt, va_list args);
void
verrx(int eval, const char *fmt, va_list args);
void
vwarn(const char *fmt, va_list args);
void
vwarnc(int code, const char *fmt, va_list args);
void
vwarnx(const char *fmt, va_list args);
๐ DESCRIPTION ๐
okay so the err() and warn() families are literally the same energy, they just handle exits differently. they all display a formatted error message โ either on the standard error output, or on another file if you set it up with err_set_file(). ๐
in every single case, here's what gets printed, in order:
- the last component of the program name
- a colon character
: - a space
- then, if the
fmtargument is notNULL, aprintf(3)-like formatted error message - the whole thing is terminated by a newline character โจ
now the spicy part: err(), errc(), verr(), verrc(), warn(), warnc(), vwarn(), and vwarnc() also append an error message obtained from strerror(3) โ based on a supplied error code value or the global variable errno. that message gets another colon and space in front of it, unless the fmt argument is NULL. ๐ญ
okay so this next bit is a whole saga, bestie. if the kernel returned an extended error string in addition to theerrnocode,err()prints the string with interpolated values for parameters, as provided to the corresponding invocation ofEXTERROR(9). if the extended error string was not provided, but extended error information was, or even if the string was provided and theEXTERROR_VERBOSEenvironment variable is present, an additional report is printed. that report includes at least the category of the error, the name of the source file (if known by the used version oflibc), the source line number, and parameters. and ifEXTERROR_VERBOSEis present and set to"brief", the report adds only the name of the source file (if known by the used version oflibc) and the source line number. the format of the printed string is not contractual and might be changed โ so don't @ me ๐
for errc(), verrc(), warnc(), and vwarnc(), the code argument is what's used to look up the error message. ๐
for err(), verr(), warn(), and vwarn(), it's the global variable errno doing the lookup. ๐
and errx() and warnx()? they do not append an error message. no extra lore, just vibes. โญ
now the exit girlies: err(), verr(), errc(), verrc(), errx(), and verrx() do not return โ they exit with the value of the argument eval. and it's recommended that the standard values defined in sysexits(3) be used for the value of eval. ๐
the err_set_exit() function can be used to specify a function which is called before exit(3) to perform any necessary cleanup โ passing a null function pointer for exitf resets the hook to do nothing. ๐
and err_set_file() sets the output stream used by the other functions. its vfp argument must be either a pointer to an open stream (possibly already converted to void *) or a null pointer (in which case the output stream is set to standard error). slay. โจ
๐ฆ EXAMPLES ๐ฆ
okay bestie, let's see this in action. first up: display the current errno information string and exit:
if ((p = malloc(size)) == NULL)
err(EX_OSERR, NULL);
if ((fd = open(file_name, O_RDONLY, 0)) == -1)
err(EX_NOINPUT, "%s", file_name);
display an error message and exit:
if (tm.tm_hour < START_TIME)
errx(EX_DATAERR, "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(EX_OSFILE, "%s", block_device);
warn of an error without using the global variable errno:
error = my_function(); /* returns a value from <errno.h> */
if (error != 0)
warnc(error, "my_function");
๐ SEE ALSO ๐
the whole friend group: exit(3), fmtmsg(3), printf(3), strerror(3), sysexits(3) โ go read those too, iykyk ๐
๐ STANDARDS ๐
okay so the err() and warn() families are BSD extensions. as such, they should not be used in truly portable code. use strerror() or similar functions instead. no cap, that's the vibe check. ๐ซถ
๐ HISTORY ๐
the err() and warn() functions first appeared in 4.4BSD. the err_set_exit() and err_set_file() functions first appeared in FreeBSD 2.1. the errc() and warnc() functions first appeared in FreeBSD 3.0. iconic behavior honestly. ๐
and that's a wrap bestie!! this page is brought to you by Debian, dated February 23, 2026, and it's giving official documentation energy ๐ โจ ๐
๐ฆ where this page comes from
- freebsd 15.1: base 15.1
- Copyright (c) 1993 The Regents of the University of California. All rights reserved
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms