The library has functions and variables designed to make it easy for
your program to report informative error messages in the customary
format about the failure of a library call. The functions
strerror
and perror
give you the standard error message
for a given error code; the variable
program_invocation_short_name
gives you convenient access to the
name of the program that encountered the error.
The
strerror
function maps the error code (see Checking for Errors) specified by the errnum argument to a descriptive error message string. The return value is a pointer to this string.The value errnum normally comes from the variable
errno
.You should not modify the string returned by
strerror
. Also, if you make subsequent calls tostrerror
, the string might be overwritten. (But it's guaranteed that no library function ever callsstrerror
behind your back.)The function
strerror
is declared in string.h.
The
strerror_r
function works likestrerror
but instead of returning the error message in a statically allocated buffer shared by all threads in the process, it returns a private copy for the thread. This might be either some permanent global data or a message string in the user supplied buffer starting at buf with the length of n bytes.At most n characters are written (including the NUL byte) so it is up to the user to select the buffer large enough.
This function should always be used in multi-threaded programs since there is no way to guarantee the string returned by
strerror
really belongs to the last call of the current thread.This function
strerror_r
is a GNU extension and it is declared in string.h.
This function prints an error message to the stream
stderr
; see Standard Streams. The orientation ofstderr
is not changed.If you call
perror
with a message that is either a null pointer or an empty string,perror
just prints the error message corresponding toerrno
, adding a trailing newline.If you supply a non-null message argument, then
perror
prefixes its output with this string. It adds a colon and a space character to separate the message from the error string corresponding toerrno
.The function
perror
is declared in stdio.h.
strerror
and perror
produce the exact same message for any
given error code; the precise text varies from system to system. With
the GNU C Library, the messages are fairly short; there are no multi-line
messages or embedded newlines. Each error message begins with a capital
letter and does not include any terminating punctuation.
Compatibility Note: The strerror
function was introduced
in ISO C89. Many older C systems do not support this function yet.
Many programs that don't read input from the terminal are designed to
exit if any system call fails. By convention, the error message from
such a program should start with the program's name, sans directories.
You can find that name in the variable
program_invocation_short_name
; the full file name is stored the
variable program_invocation_name
.
This variable's value is the name that was used to invoke the program running in the current process. It is the same as
argv[0]
. Note that this is not necessarily a useful file name; often it contains no directory names. See Program Arguments.
This variable's value is the name that was used to invoke the program running in the current process, with directory names removed. (That is to say, it is the same as
program_invocation_name
minus everything up to the last slash, if any.)
The library initialization code sets up both of these variables before
calling main
.
Portability Note: These two variables are GNU extensions. If
you want your program to work with non-GNU libraries, you must save the
value of argv[0]
in main
, and then strip off the directory
names yourself. We added these extensions to make it possible to write
self-contained error-reporting subroutines that require no explicit
cooperation from main
.
Here is an example showing how to handle failure to open a file
correctly. The function open_sesame
tries to open the named file
for reading and returns a stream if successful. The fopen
library function returns a null pointer if it couldn't open the file for
some reason. In that situation, open_sesame
constructs an
appropriate error message using the strerror
function, and
terminates the program. If we were going to make some other library
calls before passing the error code to strerror
, we'd have to
save it in a local variable instead, because those other library
functions might overwrite errno
in the meantime.
#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> FILE * open_sesame (char *name) { FILE *stream; errno = 0; stream = fopen (name, "r"); if (stream == NULL) { fprintf (stderr, "%s: Couldn't open file %s; %s\n", program_invocation_short_name, name, strerror (errno)); exit (EXIT_FAILURE); } else return stream; }
Using perror
has the advantage that the function is portable and
available on all systems implementing ISO C. But often the text
perror
generates is not what is wanted and there is no way to
extend or change what perror
does. The GNU coding standard, for
instance, requires error messages to be preceded by the program name and
programs which read some input files should provide information
about the input file name and the line number in case an error is
encountered while reading the file. For these occasions there are two
functions available which are widely used throughout the GNU project.
These functions are declared in error.h.
The
error
function can be used to report general problems during program execution. The format argument is a format string just like those given to theprintf
family of functions. The arguments required for the format can follow the format parameter. Just likeperror
,error
also can report an error code in textual form. But unlikeperror
the error value is explicitly passed to the function in the errnum parameter. This eliminates the problem mentioned above that the error reporting function must be called immediately after the function causing the error since otherwiseerrno
might have a different value.The
error
prints first the program name. If the application defined a global variableerror_print_progname
and points it to a function this function will be called to print the program name. Otherwise the string from the global variableprogram_name
is used. The program name is followed by a colon and a space which in turn is followed by the output produced by the format string. If the errnum parameter is non-zero the format string output is followed by a colon and a space, followed by the error message for the error code errnum. In any case is the output terminated with a newline.The output is directed to the
stderr
stream. If thestderr
wasn't oriented before the call it will be narrow-oriented afterwards.The function will return unless the status parameter has a non-zero value. In this case the function will call
exit
with the status value for its parameter and therefore never return. Iferror
returns the global variableerror_message_count
is incremented by one to keep track of the number of errors reported.
The
error_at_line
function is very similar to theerror
function. The only difference are the additional parameters fname and lineno. The handling of the other parameters is identical to that oferror
except that between the program name and the string generated by the format string additional text is inserted.Directly following the program name a colon, followed by the file name pointer to by fname, another colon, and a value of lineno is printed.
This additional output of course is meant to be used to locate an error in an input file (like a programming language source code file etc).
If the global variable
error_one_per_line
is set to a non-zero valueerror_at_line
will avoid printing consecutive messages for the same file and line. Repetition which are not directly following each other are not caught.Just like
error
this function only returned if status is zero. Otherwiseexit
is called with the non-zero value. Iferror
returns the global variableerror_message_count
is incremented by one to keep track of the number of errors reported.
As mentioned above the error
and error_at_line
functions
can be customized by defining a variable named
error_print_progname
.
If the
error_print_progname
variable is defined to a non-zero value the function pointed to is called byerror
orerror_at_line
. It is expected to print the program name or do something similarly useful.The function is expected to be print to the
stderr
stream and must be able to handle whatever orientation the stream has.The variable is global and shared by all threads.
The
error_message_count
variable is incremented whenever one of the functionserror
orerror_at_line
returns. The variable is global and shared by all threads.
The
error_one_per_line
variable influences onlyerror_at_line
. Normally theerror_at_line
function creates output for every invocation. Iferror_one_per_line
is set to a non-zero valueerror_at_line
keeps track of the last file name and line number for which an error was reported and avoid directly following messages for the same file and line. This variable is global and shared by all threads.
A program which read some input file and reports errors in it could look like this:
{ char *line = NULL; size_t len = 0; unsigned int lineno = 0; error_message_count = 0; while (! feof_unlocked (fp)) { ssize_t n = getline (&line, &len, fp); if (n <= 0) /* End of file or error. */ break; ++lineno; /* Process the line. */ ... if (Detect error in line) error_at_line (0, errval, filename, lineno, "some error text %s", some_variable); } if (error_message_count != 0) error (EXIT_FAILURE, 0, "%u errors found", error_message_count); }
error
and error_at_line
are clearly the functions of
choice and enable the programmer to write applications which follow the
GNU coding standard. The GNU C Library additionally contains functions which
are used in BSD for the same purpose. These functions are declared in
err.h. It is generally advised to not use these functions. They
are included only for compatibility.
The
warn
function is roughly equivalent to a call likeerror (0, errno, format, the parameters)
except that the global variables
error
respects and modifies are not used.
The
vwarn
function is just likewarn
except that the parameters for the handling of the format string format are passed in as an value of typeva_list
.
The
warnx
function is roughly equivalent to a call likeerror (0, 0, format, the parameters)
except that the global variables
error
respects and modifies are not used. The difference towarn
is that no error number string is printed.
The
vwarnx
function is just likewarnx
except that the parameters for the handling of the format string format are passed in as an value of typeva_list
.
The
err
function is roughly equivalent to a call likeerror (status, errno, format, the parameters)
except that the global variables
error
respects and modifies are not used and that the program is exited even if status is zero.
The
verr
function is just likeerr
except that the parameters for the handling of the format string format are passed in as an value of typeva_list
.
The
errx
function is roughly equivalent to a call likeerror (status, 0, format, the parameters)
except that the global variables
error
respects and modifies are not used and that the program is exited even if status is zero. The difference toerr
is that no error number string is printed.