mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-13 04:29:09 +08:00
202 lines
5.5 KiB
C
202 lines
5.5 KiB
C
/*************************************************************************\
|
|
* Copyright (C) Michael Kerrisk, 2018. *
|
|
* *
|
|
* This program is free software. You may use, modify, and redistribute it *
|
|
* under the terms of the GNU Lesser General Public License as published *
|
|
* by the Free Software Foundation, either version 3 or (at your option) *
|
|
* any later version. This program is distributed without any warranty. *
|
|
* See the files COPYING.lgpl-v3 and COPYING.gpl-v3 for details. *
|
|
\*************************************************************************/
|
|
|
|
/* Listing 3-3 */
|
|
|
|
/* error_functions.c
|
|
|
|
Some standard error handling routines used by various programs.
|
|
*/
|
|
#include <stdarg.h>
|
|
#include "error_functions.h"
|
|
#include "af_unix_hdr.h"
|
|
#include "ename.c.inc" /* Defines ename and MAX_ENAME */
|
|
|
|
#ifdef __GNUC__ /* Prevent 'gcc -Wall' complaining */
|
|
__attribute__ ((__noreturn__)) /* if we call this function as last */
|
|
#endif /* statement in a non-void function */
|
|
static void
|
|
terminate(Boolean useExit3)
|
|
{
|
|
char *s;
|
|
|
|
/* Dump core if EF_DUMPCORE environment variable is defined and
|
|
is a nonempty string; otherwise call exit(3) or _exit(2),
|
|
depending on the value of 'useExit3'. */
|
|
|
|
s = getenv("EF_DUMPCORE");
|
|
|
|
if (s != NULL && *s != '\0')
|
|
abort();
|
|
else if (useExit3)
|
|
exit(EXIT_FAILURE);
|
|
else
|
|
_exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Diagnose 'errno' error by:
|
|
|
|
* outputting a string containing the error name (if available
|
|
in 'ename' array) corresponding to the value in 'err', along
|
|
with the corresponding error message from strerror(), and
|
|
|
|
* outputting the caller-supplied error message specified in
|
|
'format' and 'ap'. */
|
|
|
|
static void
|
|
outputError(Boolean useErr, int err, Boolean flushStdout,
|
|
const char *format, va_list ap)
|
|
{
|
|
#define BUF_SIZE 500
|
|
char buf[BUF_SIZE], userMsg[BUF_SIZE], errText[BUF_SIZE];
|
|
|
|
vsnprintf(userMsg, BUF_SIZE, format, ap);
|
|
|
|
if (useErr)
|
|
snprintf(errText, BUF_SIZE, " [%s %s]",
|
|
(err > 0 && err <= MAX_ENAME) ?
|
|
ename[err] : "?UNKNOWN?", strerror(err));
|
|
else
|
|
snprintf(errText, BUF_SIZE, ":");
|
|
|
|
snprintf(buf, BUF_SIZE, "ERROR%s %s\n", errText, userMsg);
|
|
|
|
if (flushStdout)
|
|
fflush(stdout); /* Flush any pending stdout */
|
|
fputs(buf, stderr);
|
|
fflush(stderr); /* In case stderr is not line-buffered */
|
|
}
|
|
|
|
/* Display error message including 'errno' diagnostic, and
|
|
return to caller */
|
|
|
|
void
|
|
errMsg(const char *format, ...)
|
|
{
|
|
va_list argList;
|
|
int savedErrno;
|
|
|
|
savedErrno = errno; /* In case we change it here */
|
|
|
|
va_start(argList, format);
|
|
outputError(TRUE, errno, TRUE, format, argList);
|
|
va_end(argList);
|
|
|
|
errno = savedErrno;
|
|
}
|
|
|
|
/* Display error message including 'errno' diagnostic, and
|
|
terminate the process */
|
|
|
|
void
|
|
errExit(const char *format, ...)
|
|
{
|
|
va_list argList;
|
|
|
|
va_start(argList, format);
|
|
outputError(TRUE, errno, TRUE, format, argList);
|
|
va_end(argList);
|
|
|
|
terminate(TRUE);
|
|
}
|
|
|
|
/* Display error message including 'errno' diagnostic, and
|
|
terminate the process by calling _exit().
|
|
|
|
The relationship between this function and errExit() is analogous
|
|
to that between _exit(2) and exit(3): unlike errExit(), this
|
|
function does not flush stdout and calls _exit(2) to terminate the
|
|
process (rather than exit(3), which would cause exit handlers to be
|
|
invoked).
|
|
|
|
These differences make this function especially useful in a library
|
|
function that creates a child process that must then terminate
|
|
because of an error: the child must terminate without flushing
|
|
stdio buffers that were partially filled by the caller and without
|
|
invoking exit handlers that were established by the caller. */
|
|
|
|
void
|
|
err_exit(const char *format, ...)
|
|
{
|
|
va_list argList;
|
|
|
|
va_start(argList, format);
|
|
outputError(TRUE, errno, FALSE, format, argList);
|
|
va_end(argList);
|
|
|
|
terminate(FALSE);
|
|
}
|
|
|
|
/* The following function does the same as errExit(), but expects
|
|
the error number in 'errnum' */
|
|
|
|
void
|
|
errExitEN(int errnum, const char *format, ...)
|
|
{
|
|
va_list argList;
|
|
|
|
va_start(argList, format);
|
|
outputError(TRUE, errnum, TRUE, format, argList);
|
|
va_end(argList);
|
|
|
|
terminate(TRUE);
|
|
}
|
|
|
|
/* Print an error message (without an 'errno' diagnostic) */
|
|
|
|
void
|
|
fatal(const char *format, ...)
|
|
{
|
|
va_list argList;
|
|
|
|
va_start(argList, format);
|
|
outputError(FALSE, 0, TRUE, format, argList);
|
|
va_end(argList);
|
|
|
|
terminate(TRUE);
|
|
}
|
|
|
|
/* Print a command usage error message and terminate the process */
|
|
|
|
void
|
|
usageErr(const char *format, ...)
|
|
{
|
|
va_list argList;
|
|
|
|
fflush(stdout); /* Flush any pending stdout */
|
|
|
|
fprintf(stderr, "Usage: ");
|
|
va_start(argList, format);
|
|
vfprintf(stderr, format, argList);
|
|
va_end(argList);
|
|
|
|
fflush(stderr); /* In case stderr is not line-buffered */
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Diagnose an error in command-line arguments and
|
|
terminate the process */
|
|
|
|
void
|
|
cmdLineErr(const char *format, ...)
|
|
{
|
|
va_list argList;
|
|
|
|
fflush(stdout); /* Flush any pending stdout */
|
|
|
|
fprintf(stderr, "Command-line usage error: ");
|
|
va_start(argList, format);
|
|
vfprintf(stderr, format, argList);
|
|
va_end(argList);
|
|
|
|
fflush(stderr); /* In case stderr is not line-buffered */
|
|
exit(EXIT_FAILURE);
|
|
}
|