error(3)

โœจ error(3) โ€” the glibc error-reporting girlies โœจ

okay so bestie, welcome to error(3), aka the glow-up era of "something went wrong and I need to tell the whole terminal about it." this page covers error, error_at_line, error_message_count, error_one_per_line, and error_print_progname โ€” the glibc error reporting functions. we're in the error(3) manual page, and yes, it absolutely serves. ๐Ÿ’…


๐ŸŒธ LIBRARY ๐ŸŒธ

Standard C library โ€” that's libc, link it with -lc, mwah. ๐ŸŽ€


โœจ SYNOPSIS โœจ

#include <error.h>

void error(int status, int errnum, const char *format, ...);
void error_at_line(int status, int errnum, const char *file,
                   unsigned int line, const char *format, ...);

extern unsigned int error_message_count;
extern int error_one_per_line;

extern typeof(void (void))  *error_print_progname;

look at all those globals, she's got range fr fr ๐Ÿฆ‹


๐Ÿ’– DESCRIPTION ๐Ÿ’–

error() is your general-purpose error-reporting bestie. here's the whole ritual, in order, no skips: it flushes stdout, and then it outputs to stderr:

  1. the program name
  2. a colon and a space
  3. the message given by the printf(3)-style format string format
  4. and if errnum is nonzero โ€” a second colon and a space, followed by the string that strerror(errnum) hands over

any arguments that format needs should follow format in the argument list, standard variadic behavior, you got this. and the whole thing? terminated by a newline character. iconic. ๐ŸคŒ

the program name that error() prints is literally the value of the global variable program_invocation_name(3). and fun fact: program_invocation_name starts life with the same value as main()'s argv[0]. so if you want to change what error() calls you? just modify that variable. main character energy, you decide your own name. ๐Ÿ‘‘

now, status โ€” if it has a nonzero value, then error() calls exit(3) to terminate the program, using that given value as the exit status. no takebacks. but if status is zero, it just returns after printing the error message. chill. calm. still slaying. โœจ

โš ๏ธ heads up bestie โ€” nonzero status means error() ends your whole program via exit(3). that's not a typo, that's the deal.

error_at_line() is exactly the same as error(), except it brings two extra friends to the function: the file and line arguments. the output is just like what error() produces, except that after the program name it writes: a colon, the value of file, a colon, and the value of line. so it's giving receipts. ๐Ÿงš

the preprocessor values __LINE__ and __FILE__ may be useful when you're calling error_at_line() โ€” cute, easy, built in โ€” but you can also use other values. for example, those arguments could refer to a location in an input file. flexible queen. ๐ŸŒˆ

here's the tea on error_one_per_line: if that global variable is set nonzero, then a sequence of error_at_line() calls with the same value of file and line will result in only one message being output โ€” the first one. dedupe era. ๐Ÿ’€

and error_message_count? that global variable counts the number of messages that have been output by error() and error_at_line(). it's keeping score. we love an accountant. ๐Ÿ“

last one, and she's the special guest: error_print_progname. if this global variable is assigned the address of a function (i.e., it is not NULL), then that function is called instead of prefixing the message with the program name and colon. so you get to do the intro yourself. the function should print a suitable string to stderr. your stage, your mic. ๐ŸŽค


๐Ÿ”ฅ ATTRIBUTES ๐Ÿ”ฅ

for an explanation of the terms used in this section, see attributes(7).

  • error() โ€” Thread safety: MT-Safe locale
  • error_at_line() โ€” Thread safety: MT-Unsafe race: error_at_line/error_one_per_line locale

now let's unpack that second one because it's lowkey spicy. ๐ŸŒถ๏ธ

the internal error_one_per_line variable is accessed without any form of synchronization โ€” but since it's an int used once, it should be safe enough. (their words, not mine, but ok go off king.) and if error_one_per_line is set nonzero, the internal static variables (not exposed to users) used to hold the last printed filename and line number are accessed and modified without synchronization. the update is not atomic, and it occurs before disabling cancelation, so it can be interrupted only after one of the two variables is modified. ๐Ÿ˜ญ after that whole ordeal, error_at_line() is very much like error().

๐Ÿ’€ translation bestie: that's a genuine race condition, and the man page is telling you straight up. no cap. don't say nobody warned you.

๐Ÿ‘‘ STANDARDS ๐Ÿ‘‘

GNU. periodt.


๐ŸŒŸ SEE ALSO ๐ŸŒŸ


and that's the whole page, bestie!! ๐Ÿ’– this was error(3) from Linux man-pages 6.20, dated 2026-02-08 โ€” go forth and print your errors with style, and remember: flush stdout first, always. ๐Ÿซถ๐ŸŒธโœจ

๐Ÿ“ฆ where this page comes from
  • arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
  • nixpkgs unstable: man-pages 6.20
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms