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 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * errlog -- error logging facility for application programs 31 */ 32 33 #include <stdio.h> 34 #include <stdarg.h> 35 #include <stdlib.h> 36 #include "errlog.h" 37 38 /* Statics (this object is not threadable). */ 39 static int Severity; 40 static struct location { 41 char *l_file; 42 int l_lineno; 43 char *l_tag; 44 char *l_line; 45 } Location; 46 47 /* Indentation */ 48 static int Trace_indent; 49 /* XXX YES, its 80 spaces !@#$%^ */ 50 static char Trace_padding[] = 51 " " 52 " "; 53 54 #define INDENT &Trace_padding[80-(Trace_indent*4)] 55 #define PRINTHDR INPUT 56 57 /* 58 * errlog -- simulate the syslog printf-like interface, but 59 * with a first argument oriented toward reporting 60 * application errors. 61 */ 62 /*VARARGS2*/ 63 void 64 errlog(const int descriptor, const char *format, ...) 65 { 66 va_list ap; 67 68 va_start(ap, format); 69 if ((Severity < (descriptor & FATAL)) && 70 ((descriptor & FATAL) != FATAL)) { 71 /* We don't need to say/do anything. */ 72 return; 73 } 74 75 /* Produce the message. */ 76 (void) fflush(stdout); /* Synchronize streams. */ 77 if ((descriptor & PRINTHDR) != 0) { 78 if (Location.l_file == NULL) { 79 (void) fprintf(stderr, "programmer error, logerr " 80 "told to print file, line number, " 81 "but file was not set.\n"); 82 } else { 83 (void) fprintf(stderr, "\"%s\", line %d: ", 84 Location.l_file, Location.l_lineno); 85 } 86 } 87 88 /* Indent/outdent. */ 89 if (descriptor & INDENTED) { 90 (void) fprintf(stderr, "%s", INDENT); 91 Trace_indent = (Trace_indent < 20)? Trace_indent + 1: 20; 92 } else if (descriptor & OUTDENTED) { 93 Trace_indent = (Trace_indent > 0)? Trace_indent - 1: 0; 94 (void) fprintf(stderr, "%s", INDENT); 95 } else { 96 (void) fprintf(stderr, "%s", INDENT); 97 } 98 99 /* Print the stuff we did all this for. */ 100 (void) vfprintf(stderr, format, ap); 101 102 if ((descriptor & INPUT) && Location.l_line != NULL) { 103 /* Emit trailers. Formatting TBD. */ 104 (void) putc('\n', stderr); 105 (void) fprintf(stderr, "\tLine was: %s %s", 106 Location.l_tag, Location.l_line); 107 } 108 (void) putc('\n', stderr); 109 (void) fflush(stderr); /* No-op on Solaris. */ 110 111 if ((descriptor & FATAL) == FATAL) { 112 /* Say goodbye! */ 113 exit(1); 114 } 115 va_end(ap); 116 } 117 118 /* 119 * seterrline -- tell errlog what the context of the error is. 120 */ 121 void 122 seterrline(const int lineno, const char *file, 123 const char *tag, const char *line) 124 { 125 Location.l_lineno = lineno; 126 Location.l_file = (char *)file; 127 Location.l_tag = (char *)tag; 128 Location.l_line = (char *)line; 129 } 130 131 /* 132 * seterrseverity -- set the severity/loudness variable. 133 * This is traditionally the ``Verbosity'' level. 134 */ 135 void 136 seterrseverity(const int loudness) 137 { 138 Severity = (loudness & FATAL); 139 } 140