From b06e68ef1f6df69cc86d72356c3a002054a35fad Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 17 Aug 1995 19:51:51 +0000 Subject: Numerous miscellaneous features incorporated from Tony Bennett (tbennett@divnc.com) including the following major additions: + variable length messages + named devices + debug monitor + association tables/variables --- c/src/lib/libc/error.c | 212 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 c/src/lib/libc/error.c (limited to 'c/src/lib/libc/error.c') diff --git a/c/src/lib/libc/error.c b/c/src/lib/libc/error.c new file mode 100644 index 0000000000..8cf46f0565 --- /dev/null +++ b/c/src/lib/libc/error.c @@ -0,0 +1,212 @@ +/* + * @(#)error.c 1.2 - 95/08/02 + * + * + * report errors and panics to RTEMS' stderr. + * Currently just used by RTEMS monitor. + * + * + * $Id$ + */ + + +/* + * These routines provide general purpose error reporting. + * rtems_error reports an error to stderr and allows use of + * printf style formatting. A newline is appended to all messages. + * + * error_flag can be specified as any of the following: + * + * RTEMS_ERROR_ERRNO -- include errno text in output + * RTEMS_ERROR_PANIC -- halts local system after output + * RTEMS_ERROR_ABORT -- abort after output + * + * It can also include a rtems_status value which can be OR'd + * with the above flags. * + * + * EXAMPLE + * #include + * #include + * rtems_error(0, "stray interrupt %d", intr); + * + * EXAMPLE + * if ((status = rtems_task_create(...)) != RTEMS_SUCCCESSFUL) + * { + * rtems_error(status | RTEMS_ERROR_ABORT, + * "could not create task"); + * } + * + * EXAMPLE + * if ((fd = open(pathname, O_RDNLY)) < 0) + * { + * rtems_error(FLOSS_ERROR_ERRNO, "open of '%s' failed", pathname); + * goto failed; + * } + */ + +#include + +#include "error.h" +#include "assoc.h" + +#include +#include +#include +#include +#include +#include /* _exit() */ + +/* bug in hpux : no prototypes unless you are C++ */ +#ifdef hpux9 +char *strerror(int); +#endif + +extern char *rtems_progname; +int rtems_panic_in_progress; + +rtems_assoc_t rtems_status_assoc[] = { + { "successful completion", RTEMS_SUCCESSFUL, }, + { "returned from a thread", RTEMS_TASK_EXITTED, }, + { "multiprocessing not configured", RTEMS_MP_NOT_CONFIGURED, }, + { "invalid object name", RTEMS_INVALID_NAME, }, + { "invalid object id", RTEMS_INVALID_ID, }, + { "too many", RTEMS_TOO_MANY, }, + { "timed out waiting", RTEMS_TIMEOUT, }, + { "object deleted while waiting", RTEMS_OBJECT_WAS_DELETED, }, + { "specified size was invalid", RTEMS_INVALID_SIZE, }, + { "address specified is invalid", RTEMS_INVALID_ADDRESS, }, + { "number was invalid", RTEMS_INVALID_NUMBER, }, + { "item has not been initialized", RTEMS_NOT_DEFINED, }, + { "resources still outstanding", RTEMS_RESOURCE_IN_USE, }, + { "request not satisfied", RTEMS_UNSATISFIED, }, + { "thread is in wrong state", RTEMS_INCORRECT_STATE, }, + { "thread already in state", RTEMS_ALREADY_SUSPENDED, }, + { "illegal on calling thread", RTEMS_ILLEGAL_ON_SELF, }, + { "illegal for remote object", RTEMS_ILLEGAL_ON_REMOTE_OBJECT, }, + { "called from wrong environment", RTEMS_CALLED_FROM_ISR, }, + { "invalid thread priority", RTEMS_INVALID_PRIORITY, }, + { "invalid date/time", RTEMS_INVALID_CLOCK, }, + { "invalid node id", RTEMS_INVALID_NODE, }, + { "directive not configured", RTEMS_NOT_CONFIGURED, }, + { "not owner of resource", RTEMS_NOT_OWNER_OF_RESOURCE , }, + { "directive not implemented", RTEMS_NOT_IMPLEMENTED, }, + { "RTEMS inconsistency detected", RTEMS_INTERNAL_ERROR, }, + { "internal multiprocessing only", RTEMS_PROXY_BLOCKING, }, + { "could not get enough memory", RTEMS_NO_MEMORY, }, + { 0, 0, 0 }, +}; + + +char * +rtems_status_text( + rtems_status_code status +) +{ + return rtems_assoc_name_by_local(rtems_status_assoc, status); +} + + +static int rtems_verror( + unsigned32 error_flag, + char *printf_format, + va_list arglist +) +{ + int local_errno = 0; + int chars_written = 0; + rtems_status_code status; + + if (error_flag & RTEMS_ERROR_PANIC) + { + rtems_panic_in_progress++; + + /* disable task switches */ + _Thread_Disable_dispatch(); + + /* don't aggravate things */ + if (rtems_panic_in_progress > 2) + return 0; + } + + (void) fflush(stdout); /* in case stdout/stderr same */ + + status = error_flag & ~RTEMS_ERROR_MASK; + if (error_flag & RTEMS_ERROR_ERRNO) /* include errno? */ + local_errno = errno; + + if (_Configuration_Is_multiprocessing()) + fprintf(stderr, "[%d] ", _Configuration_MP_table->node); + + if (rtems_progname && *rtems_progname) + chars_written += fprintf(stderr, "%s: ", rtems_progname); + chars_written += vfprintf(stderr, printf_format, arglist); + + if (status) + chars_written += fprintf(stderr, " (status: %s)", rtems_status_text(status)); + + if (local_errno) + if ((local_errno > 0) && *strerror(local_errno)) + chars_written += fprintf(stderr, " (errno: %s)", strerror(local_errno)); + else + chars_written += fprintf(stderr, " (unknown errno=%d)", local_errno); + + chars_written += fprintf(stderr, "\n"); + + (void) fflush(stderr); + + if (error_flag & (RTEMS_ERROR_PANIC | RTEMS_ERROR_ABORT)) + { + if (error_flag & RTEMS_ERROR_PANIC) + { + rtems_error(0, "fatal error, exiting"); + _exit(local_errno); + } + else + { + rtems_error(0, "fatal error, aborting"); + abort(); + } + } + return chars_written; +} + + +/* + * Report an error. + * error_flag is as above; printf_format is a normal + * printf(3) format string, with its concommitant arguments. + * + * Returns the number of characters written. + */ + +int rtems_error( + int error_flag, + char *printf_format, + ... + ) +{ + va_list arglist; + int chars_written; + + va_start(arglist, printf_format); + chars_written = rtems_verror(error_flag, printf_format, arglist); + va_end(arglist); + + return chars_written; +} + +/* + * rtems_panic is shorthand for rtems_error(RTEMS_ERROR_PANIC, ...) + */ + +void rtems_panic( + char *printf_format, + ... + ) +{ + va_list arglist; + + va_start(arglist, printf_format); + (void) rtems_verror(RTEMS_ERROR_PANIC, printf_format, arglist); + va_end(arglist); +} -- cgit v1.2.3