(linenum→info "unix/slp.c:2238")

coreutils/6.9/lib/error.c

    1: /* Error handler for noninteractive utilities
    2:    Copyright (C) 1990-1998, 2000-2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
   18: 
   19: /* Written by David MacKenzie <djm@gnu.ai.mit.edu>.  */
   20: 
   21: #if !_LIBC
   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: #if !_LIBC && ENABLE_NLS
   33: # include "gettext.h"
   34: #endif
   35: 
   36: #ifdef _LIBC
   37: # include <libintl.h>
   38: # include <stdbool.h>
   39: # include <stdint.h>
   40: # include <wchar.h>
   41: # define mbsrtowcs __mbsrtowcs
   42: #endif
   43: 
   44: #if USE_UNLOCKED_IO
   45: # include "unlocked-io.h"
   46: #endif
   47: 
   48: #ifndef _
   49: # define _(String) String
   50: #endif
   51: 
   52: /* If NULL, error will flush stdout, then print on stderr the program
   53:    name, a colon and a space.  Otherwise, error will call this
   54:    function without parameters instead.  */
   55: void (*error_print_progname) (void);
   56: 
   57: /* This variable is incremented each time `error' is called.  */
   58: unsigned int error_message_count;
   59: 
   60: #ifdef _LIBC
   61: /* In the GNU C library, there is a predefined variable for this.  */
   62: 
   63: # define program_name program_invocation_name
   64: # include <errno.h>
   65: # include <limits.h>
   66: # include <libio/libioP.h>
   67: 
   68: /* In GNU libc we want do not want to use the common name `error' directly.
   69:    Instead make it a weak alias.  */
   70: extern void __error (int status, int errnum, const char *message, ...)
   71:      __attribute__ ((__format__ (__printf__, 3, 4)));
   72: extern void __error_at_line (int status, int errnum, const char *file_name,
   73:                              unsigned int line_number, const char *message,
   74:                              ...)
   75:      __attribute__ ((__format__ (__printf__, 5, 6)));;
   76: # define error __error
   77: # define error_at_line __error_at_line
   78: 
   79: # include <libio/iolibio.h>
   80: # define fflush(s) INTUSE(_IO_fflush) (s)
   81: # undef putc
   82: # define putc(c, fp) INTUSE(_IO_putc) (c, fp)
   83: 
   84: # include <bits/libc-lock.h>
   85: 
   86: #else /* not _LIBC */
   87: 
   88: # if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
   89: #  ifndef HAVE_DECL_STRERROR_R
   90: "this configure-time declaration test was not run"
   91: #  endif
   92: char *strerror_r ();
   93: # endif
   94: 
   95: /* The calling program should define program_name and set it to the
   96:    name of the executing program.  */
   97: extern char *program_name;
   98: 
   99: # if HAVE_STRERROR_R || defined strerror_r
  100: #  define __strerror_r strerror_r
  101: # endif /* HAVE_STRERROR_R || defined strerror_r */
  102: #endif  /* not _LIBC */
  103: 
  104: static void
  105: print_errno_message (int errnum)
  106: {
  107:   char const *s;
  108: 
  109: #if defined HAVE_STRERROR_R || _LIBC
  110:   char errbuf[1024];
  111: # if STRERROR_R_CHAR_P || _LIBC
  112:   s = __strerror_r (errnum, errbuf, sizeof errbuf);
  113: # else
  114:   if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0)
  115:     s = errbuf;
  116:   else
  117:     s = 0;
  118: # endif
  119: #else
  120:   s = strerror (errnum);
  121: #endif
  122: 
  123: #if !_LIBC
  124:   if (! s)
  125:     s = _("Unknown system error");
  126: #endif
  127: 
  128: #if _LIBC
  129:   __fxprintf (NULL, ": %s", s);
  130: #else
  131:   fprintf (stderr, ": %s", s);
  132: #endif
  133: }
  134: 
  135: static void
  136: error_tail (int status, int errnum, const char *message, va_list args)
  137: {
  138: #if _LIBC
  139:   if (_IO_fwide (stderr, 0) > 0)
  140:     {
  141: # define ALLOCA_LIMIT 2000
  142:       size_t len = strlen (message) + 1;
  143:       wchar_t *wmessage = NULL;
  144:       mbstate_t st;
  145:       size_t res;
  146:       const char *tmp;
  147:       bool use_malloc = false;
  148: 
  149:       while (1)
  150:         {
  151:           if (__libc_use_alloca (len * sizeof (wchar_t)))
  152:             wmessage = (wchar_t *) alloca (len * sizeof (wchar_t));
  153:           else
  154:             {
  155:               if (!use_malloc)
  156:                 wmessage = NULL;
  157: 
  158:               wchar_t *p = (wchar_t *) realloc (wmessage,
  159:                                                 len * sizeof (wchar_t));
  160:               if (p == NULL)
  161:                 {
  162:                   free (wmessage);
  163:                   fputws_unlocked (L"out of memory\n", stderr);
  164:                   return;
  165:                 }
  166:               wmessage = p;
  167:               use_malloc = true;
  168:             }
  169: 
  170:           memset (&st, '\0', sizeof (st));
  171:           tmp = message;
  172: 
  173:           res = mbsrtowcs (wmessage, &tmp, len, &st);
  174:           if (res != len)
  175:             break;
  176: 
  177:           if (__builtin_expect (len >= SIZE_MAX / 2, 0))
  178:             {
  179:               /* This really should not happen if everything is fine.  */
  180:               res = (size_t) -1;
  181:               break;
  182:             }
  183: 
  184:           len *= 2;
  185:         }
  186: 
  187:       if (res == (size_t) -1)
  188:         {
  189:           /* The string cannot be converted.  */
  190:           if (use_malloc)
  191:             {
  192:               free (wmessage);
  193:               use_malloc = false;
  194:             }
  195:           wmessage = (wchar_t *) L"???";
  196:         }
  197: 
  198:       __vfwprintf (stderr, wmessage, args);
  199: 
  200:       if (use_malloc)
  201:         free (wmessage);
  202:     }
  203:   else
  204: #endif
  205:     vfprintf (stderr, message, args);
  206:   va_end (args);
  207: 
  208:   ++error_message_count;
  209:   if (errnum)
  210:     print_errno_message (errnum);
  211: #if _LIBC
  212:   __fxprintf (NULL, "\n");
  213: #else
  214:   putc ('\n', stderr);
  215: #endif
  216:   fflush (stderr);
  217:   if (status)
  218:     exit (status);
  219: }
  220: 
  221: 
  222: /* Print the program name and error message MESSAGE, which is a printf-style
  223:    format string with optional args.
  224:    If ERRNUM is nonzero, print its corresponding system error message.
  225:    Exit with status STATUS if it is nonzero.  */
  226: void
  227: error (int status, int errnum, const char *message, ...)
  228: {
  229:   va_list args;
  230: 
  231: #if defined _LIBC && defined __libc_ptf_call
  232:   /* We do not want this call to be cut short by a thread
  233:      cancellation.  Therefore disable cancellation for now.  */
  234:   int state = PTHREAD_CANCEL_ENABLE;
  235:   __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
  236:                    0);
  237: #endif
  238: 
  239:   fflush (stdout);
  240: #ifdef _LIBC
  241:   _IO_flockfile (stderr);
  242: #endif
  243:   if (error_print_progname)
  244:     (*error_print_progname) ();
  245:   else
  246:     {
  247: #if _LIBC
  248:       __fxprintf (NULL, "%s: ", program_name);
  249: #else
  250:       fprintf (stderr, "%s: ", program_name);
  251: #endif
  252:     }
  253: 
  254:   va_start (args, message);
  255:   error_tail (status, errnum, message, args);
  256: 
  257: #ifdef _LIBC
  258:   _IO_funlockfile (stderr);
  259: # ifdef __libc_ptf_call
  260:   __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
  261: # endif
  262: #endif
  263: }
  264: ^L
  265: /* Sometimes we want to have at most one error per line.  This
  266:    variable controls whether this mode is selected or not.  */
  267: int error_one_per_line;
  268: 
  269: void
  270: error_at_line (int status, int errnum, const char *file_name,
  271:                unsigned int line_number, const char *message, ...)
  272: {
  273:   va_list args;
  274: 
  275:   if (error_one_per_line)
  276:     {
  277:       static const char *old_file_name;
  278:       static unsigned int old_line_number;
  279: 
  280:       if (old_line_number == line_number
  281:           && (file_name == old_file_name
  282:               || strcmp (old_file_name, file_name) == 0))
  283:         /* Simply return and print nothing.  */
  284:         return;
  285: 
  286:       old_file_name = file_name;
  287:       old_line_number = line_number;
  288:     }
  289: 
  290: #if defined _LIBC && defined __libc_ptf_call
  291:   /* We do not want this call to be cut short by a thread
  292:      cancellation.  Therefore disable cancellation for now.  */
  293:   int state = PTHREAD_CANCEL_ENABLE;
  294:   __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
  295:                    0);
  296: #endif
  297: 
  298:   fflush (stdout);
  299: #ifdef _LIBC
  300:   _IO_flockfile (stderr);
  301: #endif
  302:   if (error_print_progname)
  303:     (*error_print_progname) ();
  304:   else
  305:     {
  306: #if _LIBC
  307:       __fxprintf (NULL, "%s:", program_name);
  308: #else
  309:       fprintf (stderr, "%s:", program_name);
  310: #endif
  311:     }
  312: 
  313: #if _LIBC
  314:   __fxprintf (NULL, file_name != NULL ? "%s:%d: " : " ",
  315:               file_name, line_number);
  316: #else
  317:   fprintf (stderr, file_name != NULL ? "%s:%d: " : " ",
  318:            file_name, line_number);
  319: #endif
  320: 
  321:   va_start (args, message);
  322:   error_tail (status, errnum, message, args);
  323: 
  324: #ifdef _LIBC
  325:   _IO_funlockfile (stderr);
  326: # ifdef __libc_ptf_call
  327:   __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
  328: # endif
  329: #endif
  330: }
  331: 
  332: #ifdef _LIBC
  333: /* Make the weak alias.  */
  334: # undef error
  335: # undef error_at_line
  336: weak_alias (__error, error)
  337: weak_alias (__error_at_line, error_at_line)
  338: #endif
Syntax (Markdown)