### 2.3 Error Messages ¶

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.

Function: `char *` strerror `(int errnum)` ¶

  Preliminary: | MT-Safe | AS-Unsafe heap i18n | AC-Unsafe mem | See POSIX Safety Concepts.

  The `strerror` function maps the error code (see Checking for Errors) specified by the errnum argument to a descriptive error message string. The string is translated according to the current locale. 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 to `strerror` or `strerror_l`, or the thread that obtained the string exits, the returned pointer will be invalidated.

  As there is no way to restore the previous state after calling `strerror`, library code should not call this function because it may interfere with application use of `strerror`, invalidating the string pointer before the application is done using it. Instead, `strerror_r`, `snprintf` with the ‘`%m`’ or ‘`%#m`’ specifiers, `strerrorname_np`, or `strerrordesc_np` can be used instead.

  The `strerror` function preserves the value of `errno` and cannot fail.

  The function `strerror` is declared in `string.h`.

Function: `char *` strerror_l `(int errnum, locale_t locale)` ¶

  Preliminary: | MT-Safe | AS-Unsafe heap i18n | AC-Unsafe mem | See POSIX Safety Concepts.

  This function is like `strerror`, except that the returned string is translated according to locale (instead of the current locale used by `strerror`). Note that calling `strerror_l` invalidates the pointer returned by `strerror` and vice versa.

  The function `strerror_l` is defined by POSIX and is declared in `string.h`.

Function: `char *` strerror_r `(int errnum, char *buf, size_t n)` ¶

  Preliminary: | MT-Safe | AS-Unsafe i18n | AC-Unsafe | See POSIX Safety Concepts.

  The following description is for the GNU variant of the function, used if `_GNU_SOURCE` is defined. See Feature Test Macros.

  The `strerror_r` function works like `strerror` but instead of returning a pointer to a string that is managed by the GNU C Library, it can use the user supplied buffer starting at buf for storing the string.

  At most n characters are written (including the NUL byte) to buf, so it is up to the user to select a buffer large enough. Whether returned pointer points to the buf array or not depends on the errnum argument. If the result string is not stored in buf, the string will not change for the remaining execution of the program.

  The function `strerror_r` as described above is a GNU extension and it is declared in `string.h`. There is a POSIX variant of this function, described next.

Function: `int` strerror_r `(int errnum, char *buf, size_t n)` ¶

  Preliminary: | MT-Safe | AS-Unsafe i18n | AC-Unsafe | See POSIX Safety Concepts.

  This variant of the `strerror_r` function is used if a standard is selected that includes `strerror_r`, but `_GNU_SOURCE` is not defined. This POSIX variant of the function always writes the error message to the specified buffer buf of size n bytes.

  Upon success, `strerror_r` returns 0. Two more return values are used to indicate failure.

  `EINVAL` ¶

    The errnum argument does not correspond to a known error constant.

  `ERANGE` ¶

    The buffer size n is not large enough to store the entire error message.

  Even if an error is reported, `strerror_r` still writes as much of the error message to the output buffer as possible. After a call to `strerror_r`, the value of `errno` is unspecified.

  If you want to use the always-copying POSIX semantics of `strerror_r` in a program that is potentially compiled with `_GNU_SOURCE` defined, you can use `snprintf` with the ‘`%m`’ conversion specifier, like this:

      int saved_errno = errno;
      errno = errnum;
      int ret = snprintf (buf, n, "%m");
      errno = saved_errno;
      if (strerrorname_np (errnum) == NULL)
        return EINVAL;
      if (ret >= n)
        return ERANGE:
      return 0;

  This function is declared in `string.h` if it is declared at all. It is a POSIX extension.

Function: `void` perror `(const char *message)` ¶

  Preliminary: | MT-Unsafe race:stderr | AS-Unsafe corrupt i18n heap lock | AC-Unsafe corrupt lock mem fd | See POSIX Safety Concepts.

  This function prints an error message to the stream `stderr`; see Standard Streams. The orientation of `stderr` 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 to `errno`, 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 to `errno`.

  The function `perror` is declared in `stdio.h`.

Function: `const char *` strerrorname_np `(int errnum)` ¶

  | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.

  This function returns the name describing the error errnum or `NULL` if there is no known constant with this value (e.g "EINVAL" for `EINVAL`). The returned string does not change for the remaining execution of the program.

  This function is a GNU extension, declared in the header file `string.h`.

Function: `const char *` strerrordesc_np `(int errnum)` ¶

  | MT-Safe | AS-Safe | AC-Safe | See POSIX Safety Concepts.

  This function returns the message describing the error errnum or `NULL` if there is no known constant with this value (e.g "Invalid argument" for `EINVAL`). Different than `strerror` the returned description is not translated, and the returned string does not change for the remaining execution of the program.

  This function is a GNU extension, declared in the header file `string.h`.

`strerror` and `perror` produce the exact same message for any given error code under the same locale; 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.

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`.

Variable: `char *` 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 is a GNU extension and is declared in `errno.h`.

Variable: `char *` program_invocation_short_name ¶

  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.)

  This variable is a GNU extension and is declared in `errno.h`.

The library initialization code sets up both of these variables before calling `main`.

Portability Note: 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.

    #define _GNU_SOURCE

    #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`.

Function: `void` error `(int status, int errnum, const char *format, …)` ¶

  Preliminary: | MT-Safe locale | AS-Unsafe corrupt heap i18n | AC-Safe | See POSIX Safety Concepts.

  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 the `printf` family of functions. The arguments required for the format can follow the format parameter. Just like `perror`, `error` also can report an error code in textual form. But unlike `perror` 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 otherwise `errno` might have a different value.

  `error` prints first the program name. If the application defined a global variable `error_print_progname` and points it to a function this function will be called to print the program name. Otherwise the string from the global variable `program_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 the `stderr` 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. If `error` returns, the global variable `error_message_count` is incremented by one to keep track of the number of errors reported.

Function: `void` error_at_line `(int status, int errnum, const char *fname, unsigned int lineno, const char *format, …)` ¶

  Preliminary: | MT-Unsafe race:error_at_line/error_one_per_line locale | AS-Unsafe corrupt heap i18n | AC-Unsafe corrupt/error_one_per_line | See POSIX Safety Concepts.

  The `error_at_line` function is very similar to the `error` function. The only differences are the additional parameters fname and lineno. The handling of the other parameters is identical to that of `error` 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 pointed to by fname, another colon, and the 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 value `error_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 returns if status is zero. Otherwise `exit` is called with the non-zero value. If `error` returns, the global variable `error_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`.

Variable: `void (*error_print_progname)` (void) ¶

  If the `error_print_progname` variable is defined to a non-zero value the function pointed to is called by `error` or `error_at_line`. It is expected to print the program name or do something similarly useful.

  The function is expected to 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.

Variable: `unsigned int` error_message_count ¶

  The `error_message_count` variable is incremented whenever one of the functions `error` or `error_at_line` returns. The variable is global and shared by all threads.

Variable: `int` error_one_per_line ¶

  The `error_one_per_line` variable influences only `error_at_line`. Normally the `error_at_line` function creates output for every invocation. If `error_one_per_line` is set to a non-zero value `error_at_line` keeps track of the last file name and line number for which an error was reported and avoids 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.

Function: `void` warn `(const char *format, …)` ¶

  Preliminary: | MT-Safe locale | AS-Unsafe corrupt heap i18n | AC-Unsafe corrupt lock mem | See POSIX Safety Concepts.

  The `warn` function is roughly equivalent to a call like

        error (0, errno, format, the parameters)

  except that the global variables `error` respects and modifies are not used.

Function: `void` vwarn `(const char *format, va_list ap)` ¶

  Preliminary: | MT-Safe locale | AS-Unsafe corrupt heap i18n | AC-Unsafe corrupt lock mem | See POSIX Safety Concepts.

  The `vwarn` function is just like `warn` except that the parameters for the handling of the format string format are passed in as a value of type `va_list`.

Function: `void` warnx `(const char *format, …)` ¶

  Preliminary: | MT-Safe locale | AS-Unsafe corrupt heap | AC-Unsafe corrupt lock mem | See POSIX Safety Concepts.

  The `warnx` function is roughly equivalent to a call like

        error (0, 0, format, the parameters)

  except that the global variables `error` respects and modifies are not used. The difference to `warn` is that no error number string is printed.

Function: `void` vwarnx `(const char *format, va_list ap)` ¶

  Preliminary: | MT-Safe locale | AS-Unsafe corrupt heap | AC-Unsafe corrupt lock mem | See POSIX Safety Concepts.

  The `vwarnx` function is just like `warnx` except that the parameters for the handling of the format string format are passed in as a value of type `va_list`.

Function: `void` err `(int status, const char *format, …)` ¶

  Preliminary: | MT-Safe locale | AS-Unsafe corrupt heap i18n | AC-Unsafe corrupt lock mem | See POSIX Safety Concepts.

  The `err` function is roughly equivalent to a call like

        error (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.

Function: `void` verr `(int status, const char *format, va_list ap)` ¶

  Preliminary: | MT-Safe locale | AS-Unsafe corrupt heap i18n | AC-Unsafe corrupt lock mem | See POSIX Safety Concepts.

  The `verr` function is just like `err` except that the parameters for the handling of the format string format are passed in as a value of type `va_list`.

Function: `void` errx `(int status, const char *format, …)` ¶

  Preliminary: | MT-Safe locale | AS-Unsafe corrupt heap | AC-Unsafe corrupt lock mem | See POSIX Safety Concepts.

  The `errx` function is roughly equivalent to a call like

        error (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 to `err` is that no error number string is printed.

Function: `void` verrx `(int status, const char *format, va_list ap)` ¶

  Preliminary: | MT-Safe locale | AS-Unsafe corrupt heap | AC-Unsafe corrupt lock mem | See POSIX Safety Concepts.

  The `verrx` function is just like `errx` except that the parameters for the handling of the format string format are passed in as a value of type `va_list`.