1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * errlog -- error logging facility for application programs 29 */ 30 31 #include <stdio.h> 32 #include <stdarg.h> 33 #include <stdlib.h> 34 #include "errlog.h" 35 36 /* Statics (this object is not threadable). */ 37 static int Severity; 38 static struct location { 39 char *l_file; 40 int l_lineno; 41 char *l_tag; 42 char *l_line; 43 } Location; 44 45 /* Indentation */ 46 static int Trace_indent; 47 /* XXX YES, its 80 spaces !@#$%^ */ 48 static char Trace_padding[] = 49 " " 50 " "; 51 52 #define INDENT &Trace_padding[80-(Trace_indent*4)] 53 #define PRINTHDR INPUT 54 55 /* 56 * errlog -- simulate the syslog printf-like interface, but 57 * with a first argument oriented toward reporting 58 * application errors. 59 */ 60 /*VARARGS2*/ 61 void 62 errlog(const int descriptor, const char *format, ...) 63 { 64 va_list ap; 65 66 va_start(ap, format); 67 if ((Severity < (descriptor & FATAL)) && 68 ((descriptor & FATAL) != FATAL)) { 69 /* We don't need to say/do anything. */ 70 return; 71 } 72 73 /* Produce the message. */ 74 (void) fflush(stdout); /* Synchronize streams. */ 75 if ((descriptor & PRINTHDR) != 0) { 76 if (Location.l_file == NULL) { 77 (void) fprintf(stderr, "programmer error, logerr " 78 "told to print file, line number, " 79 "but file was not set.\n"); 80 } else { 81 (void) fprintf(stderr, "\"%s\", line %d: ", 82 Location.l_file, Location.l_lineno); 83 } 84 } 85 86 /* Indent/outdent. */ 87 if (descriptor & INDENTED) { 88 (void) fprintf(stderr, "%s", INDENT); 89 Trace_indent = (Trace_indent < 20)? Trace_indent + 1: 20; 90 } else if (descriptor & OUTDENTED) { 91 Trace_indent = (Trace_indent > 0)? Trace_indent - 1: 0; 92 (void) fprintf(stderr, "%s", INDENT); 93 } else { 94 (void) fprintf(stderr, "%s", INDENT); 95 } 96 97 /* Print the stuff we did all this for. */ 98 (void) vfprintf(stderr, format, ap); 99 100 if ((descriptor & INPUT) && Location.l_line != NULL) { 101 /* Emit trailers. Formatting TBD. */ 102 (void) putc('\n', stderr); 103 (void) fprintf(stderr, "\tLine was: %s %s", 104 Location.l_tag, Location.l_line); 105 } 106 (void) putc('\n', stderr); 107 (void) fflush(stderr); /* No-op on Solaris. */ 108 109 if ((descriptor & FATAL) == FATAL) { 110 /* Say goodbye! */ 111 exit(1); 112 } 113 va_end(ap); 114 } 115 116 /* 117 * seterrline -- tell errlog what the context of the error is. 118 */ 119 void 120 seterrline(const int lineno, const char *file, 121 const char *tag, const char *line) 122 { 123 Location.l_lineno = lineno; 124 Location.l_file = (char *)file; 125 Location.l_tag = (char *)tag; 126 Location.l_line = (char *)line; 127 } 128 129 /* 130 * seterrseverity -- set the severity/loudness variable. 131 * This is traditionally the ``Verbosity'' level. 132 */ 133 void 134 seterrseverity(const int loudness) 135 { 136 Severity = (loudness & FATAL); 137 } 138