1cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Error handler for noninteractive utilities
205436638acc7c010349a69c3395f1a57c642dc62Ying Wang   Copyright (C) 1990-1998, 2000-2007, 2009-2012 Free Software Foundation, Inc.
3cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   This file is part of the GNU C Library.
4cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
505436638acc7c010349a69c3395f1a57c642dc62Ying Wang   This program is free software: you can redistribute it and/or modify
6cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   it under the terms of the GNU General Public License as published by
705436638acc7c010349a69c3395f1a57c642dc62Ying Wang   the Free Software Foundation; either version 3 of the License, or
805436638acc7c010349a69c3395f1a57c642dc62Ying Wang   (at your option) any later version.
9cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
10cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   This program is distributed in the hope that it will be useful,
11cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   but WITHOUT ANY WARRANTY; without even the implied warranty of
12cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   GNU General Public License for more details.
14cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
1505436638acc7c010349a69c3395f1a57c642dc62Ying Wang   You should have received a copy of the GNU General Public License
1605436638acc7c010349a69c3395f1a57c642dc62Ying Wang   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
18cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Written by David MacKenzie <djm@gnu.ai.mit.edu>.  */
19cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
2005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if !_LIBC
21cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# include <config.h>
22cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif
23cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
24cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include "error.h"
25cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
26cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <stdarg.h>
27cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <stdio.h>
28cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <stdlib.h>
29cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#include <string.h>
30cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
31cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#if !_LIBC && ENABLE_NLS
32cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# include "gettext.h"
3305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define _(msgid) gettext (msgid)
34cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif
35cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
36cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#ifdef _LIBC
3705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# include <libintl.h>
3805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# include <stdbool.h>
3905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# include <stdint.h>
40cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# include <wchar.h>
41cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# define mbsrtowcs __mbsrtowcs
42cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif
43cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
44cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#if USE_UNLOCKED_IO
45cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# include "unlocked-io.h"
46cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif
47cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
48cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#ifndef _
49cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# define _(String) String
50cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif
51cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
52cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* If NULL, error will flush stdout, then print on stderr the program
53cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   name, a colon and a space.  Otherwise, error will call this
54cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   function without parameters instead.  */
55cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectvoid (*error_print_progname) (void);
56cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
5705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* This variable is incremented each time 'error' is called.  */
58cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectunsigned int error_message_count;
59cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
60cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#ifdef _LIBC
61cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* In the GNU C library, there is a predefined variable for this.  */
62cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
63cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# define program_name program_invocation_name
64cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# include <errno.h>
6505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# include <limits.h>
66cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# include <libio/libioP.h>
67cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
6805436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* In GNU libc we want do not want to use the common name 'error' directly.
69cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   Instead make it a weak alias.  */
70cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectextern void __error (int status, int errnum, const char *message, ...)
71cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project     __attribute__ ((__format__ (__printf__, 3, 4)));
72cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectextern void __error_at_line (int status, int errnum, const char *file_name,
7305436638acc7c010349a69c3395f1a57c642dc62Ying Wang                             unsigned int line_number, const char *message,
7405436638acc7c010349a69c3395f1a57c642dc62Ying Wang                             ...)
75cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project     __attribute__ ((__format__ (__printf__, 5, 6)));;
76cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# define error __error
77cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# define error_at_line __error_at_line
78cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
79cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# include <libio/iolibio.h>
80cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# define fflush(s) INTUSE(_IO_fflush) (s)
81cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# undef putc
82cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# define putc(c, fp) INTUSE(_IO_putc) (c, fp)
83cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
84cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# include <bits/libc-lock.h>
85cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
86cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#else /* not _LIBC */
87cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
8805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# include <fcntl.h>
8905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# include <unistd.h>
9005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
9105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
9205436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Get declarations of the native Windows API functions.  */
9305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define WIN32_LEAN_AND_MEAN
9405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  include <windows.h>
9505436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Get _get_osfhandle.  */
9605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  include "msvc-nothrow.h"
9705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif
9805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
9905436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* The gnulib override of fcntl is not needed in this file.  */
10005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# undef fcntl
10105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
10205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if !HAVE_DECL_STRERROR_R
103cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#  ifndef HAVE_DECL_STRERROR_R
104cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project"this configure-time declaration test was not run"
105cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#  endif
10605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  if STRERROR_R_CHAR_P
107cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectchar *strerror_r ();
10805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  else
10905436638acc7c010349a69c3395f1a57c642dc62Ying Wangint strerror_r ();
11005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  endif
111cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# endif
112cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
113cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* The calling program should define program_name and set it to the
114cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   name of the executing program.  */
115cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectextern char *program_name;
116cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
117cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# if HAVE_STRERROR_R || defined strerror_r
118cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#  define __strerror_r strerror_r
11905436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif /* HAVE_STRERROR_R || defined strerror_r */
12005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif  /* not _LIBC */
12105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
12205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if !_LIBC
12305436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Return non-zero if FD is open.  */
12405436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic int
12505436638acc7c010349a69c3395f1a57c642dc62Ying Wangis_open (int fd)
12605436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
12705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
12805436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* On native Windows: The initial state of unassigned standard file
12905436638acc7c010349a69c3395f1a57c642dc62Ying Wang     descriptors is that they are open but point to an INVALID_HANDLE_VALUE.
13005436638acc7c010349a69c3395f1a57c642dc62Ying Wang     There is no fcntl, and the gnulib replacement fcntl does not support
13105436638acc7c010349a69c3395f1a57c642dc62Ying Wang     F_GETFL.  */
13205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
13305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# else
13405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  ifndef F_GETFL
13505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#   error Please port fcntl to your platform
13605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  endif
13705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  return 0 <= fcntl (fd, F_GETFL);
13805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif
13905436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
14005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif
14105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
14205436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic void
14305436638acc7c010349a69c3395f1a57c642dc62Ying Wangflush_stdout (void)
14405436638acc7c010349a69c3395f1a57c642dc62Ying Wang{
14505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if !_LIBC
14605436638acc7c010349a69c3395f1a57c642dc62Ying Wang  int stdout_fd;
14705436638acc7c010349a69c3395f1a57c642dc62Ying Wang
14805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if GNULIB_FREOPEN_SAFER
14905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* Use of gnulib's freopen-safer module normally ensures that
15005436638acc7c010349a69c3395f1a57c642dc62Ying Wang       fileno (stdout) == 1
15105436638acc7c010349a69c3395f1a57c642dc62Ying Wang     whenever stdout is open.  */
15205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  stdout_fd = STDOUT_FILENO;
15305436638acc7c010349a69c3395f1a57c642dc62Ying Wang# else
15405436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* POSIX states that fileno (stdout) after fclose is unspecified.  But in
15505436638acc7c010349a69c3395f1a57c642dc62Ying Wang     practice it is not a problem, because stdout is statically allocated and
15605436638acc7c010349a69c3395f1a57c642dc62Ying Wang     the fd of a FILE stream is stored as a field in its allocated memory.  */
15705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  stdout_fd = fileno (stdout);
158cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# endif
15905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  /* POSIX states that fflush (stdout) after fclose is unspecified; it
16005436638acc7c010349a69c3395f1a57c642dc62Ying Wang     is safe in glibc, but not on all other platforms.  fflush (NULL)
16105436638acc7c010349a69c3395f1a57c642dc62Ying Wang     is always defined, but too draconian.  */
16205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (0 <= stdout_fd && is_open (stdout_fd))
16305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif
16405436638acc7c010349a69c3395f1a57c642dc62Ying Wang    fflush (stdout);
16505436638acc7c010349a69c3395f1a57c642dc62Ying Wang}
166cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
167cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectstatic void
168cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectprint_errno_message (int errnum)
169cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{
17005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  char const *s;
171cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
172cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#if defined HAVE_STRERROR_R || _LIBC
173cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  char errbuf[1024];
174cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# if STRERROR_R_CHAR_P || _LIBC
175cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  s = __strerror_r (errnum, errbuf, sizeof errbuf);
176cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# else
177cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0)
178cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    s = errbuf;
17905436638acc7c010349a69c3395f1a57c642dc62Ying Wang  else
18005436638acc7c010349a69c3395f1a57c642dc62Ying Wang    s = 0;
181cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# endif
18205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#else
18305436638acc7c010349a69c3395f1a57c642dc62Ying Wang  s = strerror (errnum);
184cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif
185cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
186cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#if !_LIBC
18705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  if (! s)
188cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    s = _("Unknown system error");
189cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif
190cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
191cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#if _LIBC
19205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  __fxprintf (NULL, ": %s", s);
19305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#else
194cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  fprintf (stderr, ": %s", s);
19505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif
196cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project}
197cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
198cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectstatic void
199cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projecterror_tail (int status, int errnum, const char *message, va_list args)
200cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{
201cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#if _LIBC
202cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  if (_IO_fwide (stderr, 0) > 0)
203cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    {
204cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# define ALLOCA_LIMIT 2000
205cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      size_t len = strlen (message) + 1;
20605436638acc7c010349a69c3395f1a57c642dc62Ying Wang      wchar_t *wmessage = NULL;
20705436638acc7c010349a69c3395f1a57c642dc62Ying Wang      mbstate_t st;
20805436638acc7c010349a69c3395f1a57c642dc62Ying Wang      size_t res;
20905436638acc7c010349a69c3395f1a57c642dc62Ying Wang      const char *tmp;
21005436638acc7c010349a69c3395f1a57c642dc62Ying Wang      bool use_malloc = false;
21105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
21205436638acc7c010349a69c3395f1a57c642dc62Ying Wang      while (1)
21305436638acc7c010349a69c3395f1a57c642dc62Ying Wang        {
21405436638acc7c010349a69c3395f1a57c642dc62Ying Wang          if (__libc_use_alloca (len * sizeof (wchar_t)))
21505436638acc7c010349a69c3395f1a57c642dc62Ying Wang            wmessage = (wchar_t *) alloca (len * sizeof (wchar_t));
21605436638acc7c010349a69c3395f1a57c642dc62Ying Wang          else
21705436638acc7c010349a69c3395f1a57c642dc62Ying Wang            {
21805436638acc7c010349a69c3395f1a57c642dc62Ying Wang              if (!use_malloc)
21905436638acc7c010349a69c3395f1a57c642dc62Ying Wang                wmessage = NULL;
22005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
22105436638acc7c010349a69c3395f1a57c642dc62Ying Wang              wchar_t *p = (wchar_t *) realloc (wmessage,
22205436638acc7c010349a69c3395f1a57c642dc62Ying Wang                                                len * sizeof (wchar_t));
22305436638acc7c010349a69c3395f1a57c642dc62Ying Wang              if (p == NULL)
22405436638acc7c010349a69c3395f1a57c642dc62Ying Wang                {
22505436638acc7c010349a69c3395f1a57c642dc62Ying Wang                  free (wmessage);
22605436638acc7c010349a69c3395f1a57c642dc62Ying Wang                  fputws_unlocked (L"out of memory\n", stderr);
22705436638acc7c010349a69c3395f1a57c642dc62Ying Wang                  return;
22805436638acc7c010349a69c3395f1a57c642dc62Ying Wang                }
22905436638acc7c010349a69c3395f1a57c642dc62Ying Wang              wmessage = p;
23005436638acc7c010349a69c3395f1a57c642dc62Ying Wang              use_malloc = true;
23105436638acc7c010349a69c3395f1a57c642dc62Ying Wang            }
23205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
23305436638acc7c010349a69c3395f1a57c642dc62Ying Wang          memset (&st, '\0', sizeof (st));
23405436638acc7c010349a69c3395f1a57c642dc62Ying Wang          tmp = message;
23505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
23605436638acc7c010349a69c3395f1a57c642dc62Ying Wang          res = mbsrtowcs (wmessage, &tmp, len, &st);
23705436638acc7c010349a69c3395f1a57c642dc62Ying Wang          if (res != len)
23805436638acc7c010349a69c3395f1a57c642dc62Ying Wang            break;
23905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
24005436638acc7c010349a69c3395f1a57c642dc62Ying Wang          if (__builtin_expect (len >= SIZE_MAX / 2, 0))
24105436638acc7c010349a69c3395f1a57c642dc62Ying Wang            {
24205436638acc7c010349a69c3395f1a57c642dc62Ying Wang              /* This really should not happen if everything is fine.  */
24305436638acc7c010349a69c3395f1a57c642dc62Ying Wang              res = (size_t) -1;
24405436638acc7c010349a69c3395f1a57c642dc62Ying Wang              break;
24505436638acc7c010349a69c3395f1a57c642dc62Ying Wang            }
24605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
24705436638acc7c010349a69c3395f1a57c642dc62Ying Wang          len *= 2;
24805436638acc7c010349a69c3395f1a57c642dc62Ying Wang        }
24905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
25005436638acc7c010349a69c3395f1a57c642dc62Ying Wang      if (res == (size_t) -1)
25105436638acc7c010349a69c3395f1a57c642dc62Ying Wang        {
25205436638acc7c010349a69c3395f1a57c642dc62Ying Wang          /* The string cannot be converted.  */
25305436638acc7c010349a69c3395f1a57c642dc62Ying Wang          if (use_malloc)
25405436638acc7c010349a69c3395f1a57c642dc62Ying Wang            {
25505436638acc7c010349a69c3395f1a57c642dc62Ying Wang              free (wmessage);
25605436638acc7c010349a69c3395f1a57c642dc62Ying Wang              use_malloc = false;
25705436638acc7c010349a69c3395f1a57c642dc62Ying Wang            }
25805436638acc7c010349a69c3395f1a57c642dc62Ying Wang          wmessage = (wchar_t *) L"???";
25905436638acc7c010349a69c3395f1a57c642dc62Ying Wang        }
260cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
261cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      __vfwprintf (stderr, wmessage, args);
26205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
26305436638acc7c010349a69c3395f1a57c642dc62Ying Wang      if (use_malloc)
26405436638acc7c010349a69c3395f1a57c642dc62Ying Wang        free (wmessage);
265cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    }
266cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  else
267cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif
268cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    vfprintf (stderr, message, args);
269cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  va_end (args);
270cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
271cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  ++error_message_count;
272cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  if (errnum)
273cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    print_errno_message (errnum);
274cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#if _LIBC
27505436638acc7c010349a69c3395f1a57c642dc62Ying Wang  __fxprintf (NULL, "\n");
27605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#else
27705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  putc ('\n', stderr);
278cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif
279cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  fflush (stderr);
280cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  if (status)
281cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    exit (status);
282cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project}
283cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
284cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
285cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Print the program name and error message MESSAGE, which is a printf-style
286cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   format string with optional args.
287cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   If ERRNUM is nonzero, print its corresponding system error message.
288cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   Exit with status STATUS if it is nonzero.  */
289cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectvoid
290cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projecterror (int status, int errnum, const char *message, ...)
291cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{
292cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  va_list args;
293cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
294cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#if defined _LIBC && defined __libc_ptf_call
295cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  /* We do not want this call to be cut short by a thread
296cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project     cancellation.  Therefore disable cancellation for now.  */
297cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  int state = PTHREAD_CANCEL_ENABLE;
298cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
29905436638acc7c010349a69c3395f1a57c642dc62Ying Wang                   0);
300cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif
301cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
30205436638acc7c010349a69c3395f1a57c642dc62Ying Wang  flush_stdout ();
303cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#ifdef _LIBC
304cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  _IO_flockfile (stderr);
305cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif
306cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  if (error_print_progname)
307cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    (*error_print_progname) ();
308cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  else
309cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    {
310cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#if _LIBC
31105436638acc7c010349a69c3395f1a57c642dc62Ying Wang      __fxprintf (NULL, "%s: ", program_name);
31205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#else
31305436638acc7c010349a69c3395f1a57c642dc62Ying Wang      fprintf (stderr, "%s: ", program_name);
314cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif
315cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    }
316cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
317cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  va_start (args, message);
318cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  error_tail (status, errnum, message, args);
319cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
320cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#ifdef _LIBC
321cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  _IO_funlockfile (stderr);
322cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# ifdef __libc_ptf_call
323cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
324cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# endif
325cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif
326cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project}
327cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
328cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Sometimes we want to have at most one error per line.  This
329cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project   variable controls whether this mode is selected or not.  */
330cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectint error_one_per_line;
331cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
332cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectvoid
333cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projecterror_at_line (int status, int errnum, const char *file_name,
33405436638acc7c010349a69c3395f1a57c642dc62Ying Wang               unsigned int line_number, const char *message, ...)
335cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project{
336cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  va_list args;
337cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
338cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  if (error_one_per_line)
339cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    {
340cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      static const char *old_file_name;
341cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      static unsigned int old_line_number;
342cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
343cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      if (old_line_number == line_number
34405436638acc7c010349a69c3395f1a57c642dc62Ying Wang          && (file_name == old_file_name
34505436638acc7c010349a69c3395f1a57c642dc62Ying Wang              || strcmp (old_file_name, file_name) == 0))
34605436638acc7c010349a69c3395f1a57c642dc62Ying Wang        /* Simply return and print nothing.  */
34705436638acc7c010349a69c3395f1a57c642dc62Ying Wang        return;
348cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
349cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      old_file_name = file_name;
350cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project      old_line_number = line_number;
351cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    }
352cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
353cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#if defined _LIBC && defined __libc_ptf_call
354cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  /* We do not want this call to be cut short by a thread
355cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project     cancellation.  Therefore disable cancellation for now.  */
356cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  int state = PTHREAD_CANCEL_ENABLE;
357cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
35805436638acc7c010349a69c3395f1a57c642dc62Ying Wang                   0);
359cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif
360cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
36105436638acc7c010349a69c3395f1a57c642dc62Ying Wang  flush_stdout ();
362cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#ifdef _LIBC
363cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  _IO_flockfile (stderr);
364cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif
365cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  if (error_print_progname)
366cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    (*error_print_progname) ();
367cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  else
368cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    {
369cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#if _LIBC
37005436638acc7c010349a69c3395f1a57c642dc62Ying Wang      __fxprintf (NULL, "%s:", program_name);
37105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#else
37205436638acc7c010349a69c3395f1a57c642dc62Ying Wang      fprintf (stderr, "%s:", program_name);
373cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif
374cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project    }
375cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
376cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#if _LIBC
37705436638acc7c010349a69c3395f1a57c642dc62Ying Wang  __fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ",
37805436638acc7c010349a69c3395f1a57c642dc62Ying Wang              file_name, line_number);
37905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#else
38005436638acc7c010349a69c3395f1a57c642dc62Ying Wang  fprintf (stderr, file_name != NULL ? "%s:%d: " : " ",
38105436638acc7c010349a69c3395f1a57c642dc62Ying Wang           file_name, line_number);
382cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif
383cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
384cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  va_start (args, message);
385cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  error_tail (status, errnum, message, args);
386cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
387cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#ifdef _LIBC
388cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  _IO_funlockfile (stderr);
389cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# ifdef __libc_ptf_call
390cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project  __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
391cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# endif
392cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif
393cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project}
394cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project
395cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#ifdef _LIBC
396cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project/* Make the weak alias.  */
397cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# undef error
398cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project# undef error_at_line
399cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectweak_alias (__error, error)
400cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Projectweak_alias (__error_at_line, error_at_line)
401cea198a11f15a2eb071d98491ca9a8bc8cebfbc4The Android Open Source Project#endif
402