mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-10 07:10:06 +00:00
Update.
2001-08-16 Ulrich Drepper <drepper@redhat.com> * misc/err.c: Handle wide oriented stderr.
This commit is contained in:
parent
8e2949409c
commit
a26353616e
@ -1,3 +1,7 @@
|
|||||||
|
2001-08-16 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* misc/err.c: Handle wide oriented stderr.
|
||||||
|
|
||||||
2001-08-14 Tom Rix <trix@redhat.com>
|
2001-08-14 Tom Rix <trix@redhat.com>
|
||||||
|
|
||||||
* iconv/gconv_cache.c (find_module): Add #ifndef STATIC_GCONV.
|
* iconv/gconv_cache.c (find_module): Add #ifndef STATIC_GCONV.
|
||||||
|
@ -1272,7 +1272,8 @@ This function @code{strerror_r} is a GNU extension and it is declared in
|
|||||||
@comment ISO
|
@comment ISO
|
||||||
@deftypefun void perror (const char *@var{message})
|
@deftypefun void perror (const char *@var{message})
|
||||||
This function prints an error message to the stream @code{stderr};
|
This function prints an error message to the stream @code{stderr};
|
||||||
see @ref{Standard Streams}.
|
see @ref{Standard Streams}. The orientation of @code{stderr} is not
|
||||||
|
changed.
|
||||||
|
|
||||||
If you call @code{perror} with a @var{message} that is either a null
|
If you call @code{perror} with a @var{message} that is either a null
|
||||||
pointer or an empty string, @code{perror} just prints the error message
|
pointer or an empty string, @code{perror} just prints the error message
|
||||||
@ -1292,9 +1293,8 @@ GNU system, the messages are fairly short; there are no multi-line
|
|||||||
messages or embedded newlines. Each error message begins with a capital
|
messages or embedded newlines. Each error message begins with a capital
|
||||||
letter and does not include any terminating punctuation.
|
letter and does not include any terminating punctuation.
|
||||||
|
|
||||||
@strong{Compatibility Note:} The @code{strerror} function is a new
|
@strong{Compatibility Note:} The @code{strerror} function was introduced
|
||||||
feature of @w{ISO C}. Many older C systems do not support this function
|
in @w{ISO C89}. Many older C systems do not support this function yet.
|
||||||
yet.
|
|
||||||
|
|
||||||
@cindex program name
|
@cindex program name
|
||||||
@cindex name of running program
|
@cindex name of running program
|
||||||
@ -1367,3 +1367,237 @@ open_sesame (char *name)
|
|||||||
return stream;
|
return stream;
|
||||||
@}
|
@}
|
||||||
@end smallexample
|
@end smallexample
|
||||||
|
|
||||||
|
Using @code{perror} has the advantage that the function is portable and
|
||||||
|
available on all systems implementing @w{ISO C}. But often the text
|
||||||
|
@code{perror} generates is not what is wanted and there is no way to
|
||||||
|
extend or change what @code{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 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 @file{error.h}.
|
||||||
|
|
||||||
|
@comment error.h
|
||||||
|
@comment GNU
|
||||||
|
@deftypefun void error (int @var{status}, int @var{errnum}, const char *@var{format}, @dots{})
|
||||||
|
The @code{error} function can be used to report general problems during
|
||||||
|
program execution. The @var{format} argument is a format string just
|
||||||
|
like those given to the @code{printf} family of functions. The
|
||||||
|
arguments required for the format can follow the @var{format} parameter.
|
||||||
|
Just like @code{perror}, @code{error} also can report an error code in
|
||||||
|
textual form. But unlike @code{perror} the error value is explicitly
|
||||||
|
passed to the function in the @var{errnum} parameter. This elimintates
|
||||||
|
the problem mentioned above that the error reporting function must be
|
||||||
|
called immediately after the function causing the error since otherwise
|
||||||
|
@code{errno} might have a different value.
|
||||||
|
|
||||||
|
The @code{error} prints first the program name. If the application
|
||||||
|
defined a global variable @code{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 @code{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
|
||||||
|
@var{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
|
||||||
|
@var{errnum}. In any case is the output terminated with a newline.
|
||||||
|
|
||||||
|
The output is directed to the @code{stderr} stream. If the
|
||||||
|
@code{stderr} wasn't oriented before the call it will be narrow-oriented
|
||||||
|
afterwards.
|
||||||
|
|
||||||
|
The function will return unless the @var{status} parameter has a
|
||||||
|
non-zero value. In this case the function will call @code{exit} with
|
||||||
|
the @var{status} value for its parameter and therefore never return. If
|
||||||
|
@code{error} returns the global variable @code{error_message_count} is
|
||||||
|
incremented by one to keep track of the number of errors reported.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@comment error.h
|
||||||
|
@comment GNU
|
||||||
|
@deftypefun void error_at_line (int @var{status}, int @var{errnum}, const char *@var{fname}, unsigned int @var{lineno}, const char *@var{format}, @dots{})
|
||||||
|
|
||||||
|
The @code{error_at_line} function is very similar to the @code{error}
|
||||||
|
function. The only difference are the additional parameters @var{fname}
|
||||||
|
and @var{lineno}. The handling of the other parameters is identical to
|
||||||
|
that of @code{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
|
||||||
|
pointer to by @var{fname}, another colon, and a value of @var{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 @code{error_one_per_line} is set to a non-zero
|
||||||
|
value @code{error_at_line} will avoid printing consecutive messages for
|
||||||
|
the same file anem line. Repetition which are not directly following
|
||||||
|
each other are not caught.
|
||||||
|
|
||||||
|
Just like @code{error} this function only returned if @var{status} is
|
||||||
|
zero. Otherwise @code{exit} is called with the non-zero value. If
|
||||||
|
@code{error} returns the global variable @code{error_message_count} is
|
||||||
|
incremented by one to keep track of the number of errors reported.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
As mentioned above the @code{error} and @code{error_at_line} functions
|
||||||
|
can be customized by defining a variable named
|
||||||
|
@code{error_print_progname}.
|
||||||
|
|
||||||
|
@comment error.h
|
||||||
|
@comment GNU
|
||||||
|
@deftypevar {void (*} error_print_progname ) (void)
|
||||||
|
If the @code{error_print_progname} variable is defined to a non-zero
|
||||||
|
value the function pointed to is called by @code{error} or
|
||||||
|
@code{error_at_line}. It is expected to print the program name or do
|
||||||
|
something similarly useful.
|
||||||
|
|
||||||
|
The function is expected to be print to the @code{stderr} stream and
|
||||||
|
must be able to handle whatever orientation the stream has.
|
||||||
|
|
||||||
|
The variable is global and shared by all threads.
|
||||||
|
@end deftypevar
|
||||||
|
|
||||||
|
@comment error.h
|
||||||
|
@comment GNU
|
||||||
|
@deftypevar {unsigned int} error_message_count
|
||||||
|
The @code{error_message_count} variable is incremented whenever one of
|
||||||
|
the functions @code{error} or @code{error_at_line} returns. The
|
||||||
|
variable is global and shared by all threads.
|
||||||
|
@end deftypevar
|
||||||
|
|
||||||
|
@comment error.h
|
||||||
|
@comment GNU
|
||||||
|
@deftypevar int error_one_per_line
|
||||||
|
The @code{error_one_per_line} variable influences only
|
||||||
|
@code{error_at_line}. Normally the @code{error_at_line} function
|
||||||
|
creates output for every invocation. If @code{error_one_per_line} is
|
||||||
|
set to a non-zero value @code{error_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.
|
||||||
|
@end deftypevar
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
A program which read some input file and reports errors in it could look
|
||||||
|
like this:
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
@{
|
||||||
|
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)
|
||||||
|
/* @r{End of file or error.} */
|
||||||
|
break;
|
||||||
|
++lineno;
|
||||||
|
|
||||||
|
/* @r{Process the line.} */
|
||||||
|
@dots{}
|
||||||
|
|
||||||
|
if (@r{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);
|
||||||
|
@}
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
@code{error} and @code{error_at_line} are clearly the functions of
|
||||||
|
choice and enable the programmer to write applications which follow the
|
||||||
|
GNU coding standard. The GNU libc additionally contains functions which
|
||||||
|
are used in BSD for the same purpose. These functions are declared in
|
||||||
|
@file{err.h}. It is generally advised to not use these functions. They
|
||||||
|
are included only for compatibility.
|
||||||
|
|
||||||
|
@comment err.h
|
||||||
|
@comment BSD
|
||||||
|
@deftypefun void warn (const char *@var{format}, @dots{})
|
||||||
|
The @code{warn} function is roughly equivalent to a call like
|
||||||
|
@smallexample
|
||||||
|
error (0, errno, format, @r{the parameters})
|
||||||
|
@end smallexample
|
||||||
|
@noindent
|
||||||
|
except that the global variables @code{error} respects and modifies
|
||||||
|
are not used.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@comment err.h
|
||||||
|
@comment BSD
|
||||||
|
@deftypefun void vwarn (const char *@var{format}, va_list)
|
||||||
|
The @code{vwarn} function is just like @code{warn} except that the
|
||||||
|
parameters for the handling of the format string @var{format} are passed
|
||||||
|
in as an value of type @code{va_list}.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@comment err.h
|
||||||
|
@comment BSD
|
||||||
|
@deftypefun void warnx (const char *@var{format}, @dots{})
|
||||||
|
The @code{warnx} function is roughly equivalent to a call like
|
||||||
|
@smallexample
|
||||||
|
error (0, 0, format, @r{the parameters})
|
||||||
|
@end smallexample
|
||||||
|
@noindent
|
||||||
|
except that the global variables @code{error} respects and modifies
|
||||||
|
are not used. The difference to @code{warn} is that no error number
|
||||||
|
string is printed.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@comment err.h
|
||||||
|
@comment BSD
|
||||||
|
@deftypefun void vwarnx (const char *@var{format}, va_list)
|
||||||
|
The @code{vwarnx} function is just like @code{warnx} except that the
|
||||||
|
parameters for the handling of the format string @var{format} are passed
|
||||||
|
in as an value of type @code{va_list}.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@comment err.h
|
||||||
|
@comment BSD
|
||||||
|
@deftypefun void err (int @var{status}, const char *@var{format}, @dots{})
|
||||||
|
The @code{err} function is roughly equivalent to a call like
|
||||||
|
@smallexample
|
||||||
|
error (status, errno, format, @r{the parameters})
|
||||||
|
@end smallexample
|
||||||
|
@noindent
|
||||||
|
except that the global variables @code{error} respects and modifies
|
||||||
|
are not used and that the program is exited even if @var{status} is zero.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@comment err.h
|
||||||
|
@comment BSD
|
||||||
|
@deftypefun void verr (int @var{status}, const char *@var{format}, va_list)
|
||||||
|
The @code{verr} function is just like @code{err} except that the
|
||||||
|
parameters for the handling of the format string @var{format} are passed
|
||||||
|
in as an value of type @code{va_list}.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@comment err.h
|
||||||
|
@comment BSD
|
||||||
|
@deftypefun void errx (int @var{status}, const char *@var{format}, @dots{})
|
||||||
|
The @code{errx} function is roughly equivalent to a call like
|
||||||
|
@smallexample
|
||||||
|
error (status, 0, format, @r{the parameters})
|
||||||
|
@end smallexample
|
||||||
|
@noindent
|
||||||
|
except that the global variables @code{error} respects and modifies
|
||||||
|
are not used and that the program is exited even if @var{status}
|
||||||
|
is zero. The difference to @code{err} is that no error number
|
||||||
|
string is printed.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@comment err.h
|
||||||
|
@comment BSD
|
||||||
|
@deftypefun void verrx (int @var{status}, const char *@var{format}, va_list)
|
||||||
|
The @code{verrx} function is just like @code{errx} except that the
|
||||||
|
parameters for the handling of the format string @var{format} are passed
|
||||||
|
in as an value of type @code{va_list}.
|
||||||
|
@end deftypefun
|
||||||
|
101
misc/err.c
101
misc/err.c
@ -1,5 +1,5 @@
|
|||||||
/* err.c --- 4.4BSD utility functions for error messages.
|
/* 4.4BSD utility functions for error messages.
|
||||||
Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
|
Copyright (C) 1995, 1996, 1998, 2001 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it and/or
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
@ -25,6 +25,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifdef USE_IN_LIBIO
|
#ifdef USE_IN_LIBIO
|
||||||
|
# include <wchar.h>
|
||||||
# define flockfile(s) _IO_flockfile (s)
|
# define flockfile(s) _IO_flockfile (s)
|
||||||
# define funlockfile(s) _IO_funlockfile (s)
|
# define funlockfile(s) _IO_funlockfile (s)
|
||||||
#endif
|
#endif
|
||||||
@ -39,15 +40,72 @@ extern char *__progname;
|
|||||||
va_end (ap); \
|
va_end (ap); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_IN_LIBIO
|
||||||
|
static void
|
||||||
|
convert_and_print (const char *format, __gnuc_va_list ap)
|
||||||
|
{
|
||||||
|
# define ALLOCA_LIMIT 2000
|
||||||
|
size_t len;
|
||||||
|
wchar_t *wformat = NULL;
|
||||||
|
mbstate_t st;
|
||||||
|
size_t res;
|
||||||
|
const char *tmp;
|
||||||
|
|
||||||
|
if (format == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
len = strlen (format) + 1;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (len < ALLOCA_LIMIT)
|
||||||
|
wformat = (wchar_t *) alloca (len * sizeof (wchar_t));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (wformat != NULL && len / 2 < ALLOCA_LIMIT)
|
||||||
|
wformat = NULL;
|
||||||
|
|
||||||
|
wformat = (wchar_t *) realloc (wformat, len * sizeof (wchar_t));
|
||||||
|
|
||||||
|
if (wformat == NULL)
|
||||||
|
{
|
||||||
|
fputws (L"out of memory\n", stderr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (&st, '\0', sizeof (st));
|
||||||
|
tmp =format;
|
||||||
|
}
|
||||||
|
while ((res = mbsrtowcs (wformat, &tmp, len, &st)) == len);
|
||||||
|
|
||||||
|
if (res == (size_t) -1)
|
||||||
|
/* The string cannot be converted. */
|
||||||
|
wformat = (wchar_t *) L"???";
|
||||||
|
|
||||||
|
vfwprintf (stderr, wformat, ap);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
vwarnx (const char *format, __gnuc_va_list ap)
|
vwarnx (const char *format, __gnuc_va_list ap)
|
||||||
{
|
{
|
||||||
flockfile (stderr);
|
flockfile (stderr);
|
||||||
if (__progname)
|
#ifdef USE_IN_LIBIO
|
||||||
fprintf (stderr, "%s: ", __progname);
|
if (_IO_fwide (stderr, 0) > 0)
|
||||||
if (format)
|
{
|
||||||
vfprintf (stderr, format, ap);
|
fwprintf (stderr, L"%s: ", __progname);
|
||||||
putc_unlocked ('\n', stderr);
|
convert_and_print (format, ap);
|
||||||
|
putwc_unlocked (L'\n', stderr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s: ", __progname);
|
||||||
|
if (format)
|
||||||
|
vfprintf (stderr, format, ap);
|
||||||
|
putc_unlocked ('\n', stderr);
|
||||||
|
}
|
||||||
funlockfile (stderr);
|
funlockfile (stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,15 +115,30 @@ vwarn (const char *format, __gnuc_va_list ap)
|
|||||||
int error = errno;
|
int error = errno;
|
||||||
|
|
||||||
flockfile (stderr);
|
flockfile (stderr);
|
||||||
if (__progname)
|
#ifdef USE_IN_LIBIO
|
||||||
fprintf (stderr, "%s: ", __progname);
|
if (_IO_fwide (stderr, 0) > 0)
|
||||||
if (format)
|
|
||||||
{
|
{
|
||||||
vfprintf (stderr, format, ap);
|
fwprintf (stderr, L"%s: ", __progname);
|
||||||
fputs_unlocked (": ", stderr);
|
if (format)
|
||||||
|
{
|
||||||
|
convert_and_print (format, ap);
|
||||||
|
fputws_unlocked (L": ", stderr);
|
||||||
|
}
|
||||||
|
__set_errno (error);
|
||||||
|
fwprintf (stderr, L"%m\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s: ", __progname);
|
||||||
|
if (format)
|
||||||
|
{
|
||||||
|
vfprintf (stderr, format, ap);
|
||||||
|
fputs_unlocked (": ", stderr);
|
||||||
|
}
|
||||||
|
__set_errno (error);
|
||||||
|
fprintf (stderr, "%m\n");
|
||||||
}
|
}
|
||||||
__set_errno (error);
|
|
||||||
fprintf (stderr, "%m\n");
|
|
||||||
funlockfile (stderr);
|
funlockfile (stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user