1/* Error handler for noninteractive utilities
2   Copyright (C) 1990-1998, 2000-2002, 2003 Free Software Foundation, Inc.
3   This file is part of the GNU C Library.
4
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 2, or (at your option)
8   any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14
15   You should have received a copy of the GNU General Public License along
16   with this program; if not, write to the Free Software Foundation,
17   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
18
19/* Written by David MacKenzie <djm@gnu.ai.mit.edu>.  */
20
21#ifdef HAVE_CONFIG_H
22# include <config.h>
23#endif
24
25#include "error.h"
26
27#include <stdarg.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31
32#ifdef _LIBC
33# include <libintl.h>
34#else
35# include "gettext.h"
36#endif
37
38#ifdef _LIBC
39# include <wchar.h>
40# define mbsrtowcs __mbsrtowcs
41#endif
42
43#if !_LIBC
44# include "unlocked-io.h"
45#endif
46
47#ifndef _
48# define _(String) String
49#endif
50
51/* If NULL, error will flush stdout, then print on stderr the program
52   name, a colon and a space.  Otherwise, error will call this
53   function without parameters instead.  */
54void (*error_print_progname) (void);
55
56/* This variable is incremented each time `error' is called.  */
57unsigned int error_message_count;
58
59#ifdef _LIBC
60/* In the GNU C library, there is a predefined variable for this.  */
61
62# define program_name program_invocation_name
63# include <errno.h>
64# include <libio/libioP.h>
65
66/* In GNU libc we want do not want to use the common name `error' directly.
67   Instead make it a weak alias.  */
68extern void __error (int status, int errnum, const char *message, ...)
69     __attribute__ ((__format__ (__printf__, 3, 4)));
70extern void __error_at_line (int status, int errnum, const char *file_name,
71			     unsigned int line_number, const char *message,
72			     ...)
73     __attribute__ ((__format__ (__printf__, 5, 6)));;
74# define error __error
75# define error_at_line __error_at_line
76
77# include <libio/iolibio.h>
78# define fflush(s) INTUSE(_IO_fflush) (s)
79# undef putc
80# define putc(c, fp) INTUSE(_IO_putc) (c, fp)
81
82# include <bits/libc-lock.h>
83
84#else /* not _LIBC */
85
86# if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
87#  ifndef HAVE_DECL_STRERROR_R
88"this configure-time declaration test was not run"
89#  endif
90char *strerror_r ();
91# endif
92
93# ifndef SIZE_MAX
94#  define SIZE_MAX ((size_t) -1)
95# endif
96
97/* The calling program should define program_name and set it to the
98   name of the executing program.  */
99extern char *program_name;
100
101# if HAVE_STRERROR_R || defined strerror_r
102#  define __strerror_r strerror_r
103# endif
104#endif	/* not _LIBC */
105
106static void
107print_errno_message (int errnum)
108{
109  char const *s;
110
111#if defined HAVE_STRERROR_R || _LIBC
112  char errbuf[1024];
113# if STRERROR_R_CHAR_P || _LIBC
114  s = __strerror_r (errnum, errbuf, sizeof errbuf);
115# else
116  if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0)
117    s = errbuf;
118  else
119    s = 0;
120# endif
121#else
122  s = strerror (errnum);
123#endif
124
125#if !_LIBC
126  if (! s)
127    s = _("Unknown system error");
128#endif
129
130#if _LIBC
131  if (_IO_fwide (stderr, 0) > 0)
132    {
133      __fwprintf (stderr, L": %s", s);
134      return;
135    }
136#endif
137
138  fprintf (stderr, ": %s", s);
139}
140
141static void
142error_tail (int status, int errnum, const char *message, va_list args)
143{
144#if _LIBC
145  if (_IO_fwide (stderr, 0) > 0)
146    {
147# define ALLOCA_LIMIT 2000
148      size_t len = strlen (message) + 1;
149      const wchar_t *wmessage = L"out of memory";
150      wchar_t *wbuf = (len < ALLOCA_LIMIT
151		       ? alloca (len * sizeof *wbuf)
152		       : len <= SIZE_MAX / sizeof *wbuf
153		       ? malloc (len * sizeof *wbuf)
154		       : NULL);
155
156      if (wbuf)
157	{
158	  size_t res;
159	  mbstate_t st;
160	  const char *tmp = message;
161	  memset (&st, '\0', sizeof (st));
162	  res = mbsrtowcs (wbuf, &tmp, len, &st);
163	  wmessage = res == (size_t) -1 ? L"???" : wbuf;
164	}
165
166      __vfwprintf (stderr, wmessage, args);
167      if (! (len < ALLOCA_LIMIT))
168	free (wbuf);
169    }
170  else
171#endif
172    vfprintf (stderr, message, args);
173  va_end (args);
174
175  ++error_message_count;
176  if (errnum)
177    print_errno_message (errnum);
178#if _LIBC
179  if (_IO_fwide (stderr, 0) > 0)
180    putwc (L'\n', stderr);
181  else
182#endif
183    putc ('\n', stderr);
184  fflush (stderr);
185  if (status)
186    exit (status);
187}
188
189
190/* Print the program name and error message MESSAGE, which is a printf-style
191   format string with optional args.
192   If ERRNUM is nonzero, print its corresponding system error message.
193   Exit with status STATUS if it is nonzero.  */
194void
195error (int status, int errnum, const char *message, ...)
196{
197  va_list args;
198
199#if defined _LIBC && defined __libc_ptf_call
200  /* We do not want this call to be cut short by a thread
201     cancellation.  Therefore disable cancellation for now.  */
202  int state = PTHREAD_CANCEL_ENABLE;
203  __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
204		   0);
205#endif
206
207  fflush (stdout);
208#ifdef _LIBC
209  _IO_flockfile (stderr);
210#endif
211  if (error_print_progname)
212    (*error_print_progname) ();
213  else
214    {
215#if _LIBC
216      if (_IO_fwide (stderr, 0) > 0)
217	__fwprintf (stderr, L"%s: ", program_name);
218      else
219#endif
220	fprintf (stderr, "%s: ", program_name);
221    }
222
223  va_start (args, message);
224  error_tail (status, errnum, message, args);
225
226#ifdef _LIBC
227  _IO_funlockfile (stderr);
228# ifdef __libc_ptf_call
229  __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
230# endif
231#endif
232}
233
234/* Sometimes we want to have at most one error per line.  This
235   variable controls whether this mode is selected or not.  */
236int error_one_per_line;
237
238void
239error_at_line (int status, int errnum, const char *file_name,
240	       unsigned int line_number, const char *message, ...)
241{
242  va_list args;
243
244  if (error_one_per_line)
245    {
246      static const char *old_file_name;
247      static unsigned int old_line_number;
248
249      if (old_line_number == line_number
250	  && (file_name == old_file_name
251	      || strcmp (old_file_name, file_name) == 0))
252	/* Simply return and print nothing.  */
253	return;
254
255      old_file_name = file_name;
256      old_line_number = line_number;
257    }
258
259#if defined _LIBC && defined __libc_ptf_call
260  /* We do not want this call to be cut short by a thread
261     cancellation.  Therefore disable cancellation for now.  */
262  int state = PTHREAD_CANCEL_ENABLE;
263  __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
264		   0);
265#endif
266
267  fflush (stdout);
268#ifdef _LIBC
269  _IO_flockfile (stderr);
270#endif
271  if (error_print_progname)
272    (*error_print_progname) ();
273  else
274    {
275#if _LIBC
276      if (_IO_fwide (stderr, 0) > 0)
277	__fwprintf (stderr, L"%s: ", program_name);
278      else
279#endif
280	fprintf (stderr, "%s:", program_name);
281    }
282
283  if (file_name != NULL)
284    {
285#if _LIBC
286      if (_IO_fwide (stderr, 0) > 0)
287	__fwprintf (stderr, L"%s:%d: ", file_name, line_number);
288      else
289#endif
290	fprintf (stderr, "%s:%d: ", file_name, line_number);
291    }
292
293  va_start (args, message);
294  error_tail (status, errnum, message, args);
295
296#ifdef _LIBC
297  _IO_funlockfile (stderr);
298# ifdef __libc_ptf_call
299  __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
300# endif
301#endif
302}
303
304#ifdef _LIBC
305/* Make the weak alias.  */
306# undef error
307# undef error_at_line
308weak_alias (__error, error)
309weak_alias (__error_at_line, error_at_line)
310#endif
311