|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1996, 1998, 1999 University of Utah and the Flux Group. ! 3: * All rights reserved. ! 4: * ! 5: * This file is part of the Flux OSKit. The OSKit is free software, also known ! 6: * as "open source;" you can redistribute it and/or modify it under the terms ! 7: * of the GNU General Public License (GPL), version 2, as published by the Free ! 8: * Software Foundation (FSF). To explore alternate licensing terms, contact ! 9: * the University of Utah at [email protected] or +1-801-585-3271. ! 10: * ! 11: * The OSKit is distributed in the hope that it will be useful, but WITHOUT ANY ! 12: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ! 13: * FOR A PARTICULAR PURPOSE. See the GPL for more details. You should have ! 14: * received a copy of the GPL along with the OSKit; see the file COPYING. If ! 15: * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA. ! 16: */ ! 17: ! 18: #include "ds_oskit.h" ! 19: ! 20: #include <stdarg.h> ! 21: #include <string.h> ! 22: ! 23: #include <oskit/com.h> ! 24: #include <oskit/dev/dev.h> ! 25: #include <oskit/dev/osenv_log.h> ! 26: #include <oskit/c/stdio.h> ! 27: #include <oskit/base_critical.h> ! 28: ! 29: #include <oskit/com/stream.h> ! 30: #include <oskit/com/trivial_stream.h> ! 31: ! 32: ! 33: /* ! 34: * There is one and only one log/panic interface in this implementation. ! 35: */ ! 36: static struct oskit_osenv_log_ops osenv_log_ops; ! 37: static struct oskit_osenv_log osenv_log_object = {&osenv_log_ops}; ! 38: ! 39: static OSKIT_COMDECL ! 40: log_query(oskit_osenv_log_t *s, const oskit_iid_t *iid, void **out_ihandle) ! 41: { ! 42: if (memcmp(iid, &oskit_iunknown_iid, sizeof(*iid)) == 0 || ! 43: memcmp(iid, &oskit_osenv_log_iid, sizeof(*iid)) == 0) { ! 44: *out_ihandle = s; ! 45: return 0; ! 46: } ! 47: ! 48: *out_ihandle = 0; ! 49: return OSKIT_E_NOINTERFACE; ! 50: }; ! 51: ! 52: static OSKIT_COMDECL_U ! 53: log_addref(oskit_osenv_log_t *s) ! 54: { ! 55: return 1; ! 56: } ! 57: ! 58: static OSKIT_COMDECL_U ! 59: log_release(oskit_osenv_log_t *s) ! 60: { ! 61: return 1; ! 62: } ! 63: ! 64: ! 65: static const char *const log_prio_names[] = ! 66: { ! 67: [OSENV_LOG_EMERG] = "EMERGENCY", ! 68: [OSENV_LOG_ALERT] = "ALERT", ! 69: [OSENV_LOG_CRIT] = "CRITICAL ERROR", ! 70: [OSENV_LOG_ERR] = "ERROR", ! 71: [OSENV_LOG_WARNING] = "WARNING", ! 72: [OSENV_LOG_NOTICE] = "NOTICE", ! 73: [OSENV_LOG_INFO] = "INFO", ! 74: [OSENV_LOG_DEBUG] = "DEBUG", ! 75: }; ! 76: ! 77: static int midline, last_prio = -1; ! 78: static int ! 79: cooked_putchar (int c) ! 80: { ! 81: oskit_error_t rc; ! 82: oskit_u32_t actual; ! 83: ! 84: if (!midline) ! 85: { ! 86: com_printf(kmsg_stream, "<%u>", last_prio); ! 87: if (last_prio < OSENV_LOG_DEBUG && kmsg_readers == 0) ! 88: { ! 89: if (last_prio == OSENV_LOG_INFO) ! 90: com_printf (ds_console_stream, "(device driver): "); ! 91: else ! 92: com_printf (ds_console_stream, "(device driver) %s: ", ! 93: log_prio_names[last_prio]); ! 94: } ! 95: } ! 96: ! 97: midline = (c != '\n'); ! 98: ! 99: if (last_prio >= OSENV_LOG_DEBUG || kmsg_readers) ! 100: return (unsigned char)c; ! 101: ! 102: if (c == '\n') ! 103: rc = oskit_stream_write (ds_console_stream, "\r\n", 2, &actual); ! 104: else ! 105: { ! 106: unsigned char cc = c; ! 107: rc = oskit_stream_write (ds_console_stream, &cc, 1, &actual); ! 108: } ! 109: ! 110: return OSKIT_FAILED(rc) ? -1 : (unsigned char)c; ! 111: } ! 112: static struct oskit_trivial_stream log_impl = ! 113: { { &oskit_trivial_stream_ops }, putchar: cooked_putchar }; ! 114: ! 115: ! 116: static OSKIT_COMDECL_V ! 117: log_vlog(oskit_osenv_log_t *o, int priority, const char *fmt, void *args) ! 118: { ! 119: base_critical_enter(); ! 120: ! 121: if (priority != last_prio) ! 122: { ! 123: midline = 0; ! 124: last_prio = priority; ! 125: } ! 126: ! 127: /* This run prints to the console if that's enabled, ! 128: and it maintains the "midline" state and prints a ! 129: priority token to the kmsg stream for each new line. ! 130: We assume there will be at most one new line per call. */ ! 131: com_vprintf(&log_impl.streami, fmt, args); ! 132: ! 133: /* Now this run writes the message to the kmsg stream, ! 134: after any priority token written by above. */ ! 135: com_vprintf(kmsg_stream, fmt, args); ! 136: ! 137: base_critical_leave(); ! 138: } ! 139: ! 140: static OSKIT_COMDECL_V ! 141: log_log(oskit_osenv_log_t *o, int priority, const char *fmt, ...) ! 142: { ! 143: va_list args; ! 144: ! 145: va_start(args, fmt); ! 146: log_vlog(o, priority, fmt, args); ! 147: va_end(args); ! 148: } ! 149: ! 150: static OSKIT_COMDECL_V ! 151: log_vpanic(oskit_osenv_log_t *o, const char *fmt, void *args) ! 152: { ! 153: log_vlog(o, OSENV_LOG_EMERG, fmt, args); ! 154: ! 155: vprintf(fmt, args); ! 156: panic("\r\npanic in device driver!"); ! 157: } ! 158: ! 159: static OSKIT_COMDECL_V ! 160: log_panic(oskit_osenv_log_t *o, const char *fmt, ...) ! 161: { ! 162: va_list args; ! 163: ! 164: va_start(args, fmt); ! 165: log_vpanic(o, fmt, args); ! 166: va_end(args); ! 167: } ! 168: ! 169: static struct oskit_osenv_log_ops osenv_log_ops = { ! 170: log_query, ! 171: log_addref, ! 172: log_release, ! 173: log_log, ! 174: log_vlog, ! 175: log_panic, ! 176: log_vpanic, ! 177: }; ! 178: ! 179: ! 180: /* ! 181: * Return a reference to the one and only interrupt object. ! 182: */ ! 183: oskit_osenv_log_t * ! 184: oskit_create_osenv_log(void) ! 185: { ! 186: return &osenv_log_object; ! 187: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.