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 2003 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 #include "med_local.h"
30
31 #include <syslog.h>
32
33 /*
34 * debug stuff
35 */
36 #define MED_DEBUG 0
37 #ifdef MED_DEBUG
38 static int med_debug = MED_DEBUG;
39 #endif
40
41 /*
42 * free and clear error
43 */
44 static void
med_clrerror(med_err_t * medep)45 med_clrerror(
46 med_err_t *medep
47 )
48 {
49 if (medep->med_node != NULL)
50 Free(medep->med_node);
51 if (medep->med_misc != NULL)
52 Free(medep->med_misc);
53 (void) memset(medep, 0, sizeof (*medep));
54 }
55
56 /*
57 * Exported Entry Points
58 */
59
60 /*
61 * setup error
62 */
63 int
med_error(med_err_t * medep,int errnum,char * misc)64 med_error(
65 med_err_t *medep,
66 int errnum,
67 char *misc
68 )
69 {
70 med_clrerror(medep);
71 if (errnum != 0) {
72 medep->med_errno = errnum;
73 if (med_debug && misc != NULL)
74 medep->med_misc = Strdup(misc);
75 medep->med_node = Strdup(mynode());
76 return (-1);
77 }
78 return (0);
79 }
80
81 /*
82 * med_err_t to string
83 */
84 static char *
med_strerror(med_err_t * medep)85 med_strerror(
86 med_err_t *medep
87 )
88 {
89 static char buf[1024];
90 char *p = buf;
91 char *emsg;
92
93 if (medep->med_errno < 0) {
94 if ((emsg = med_errnum_to_str(medep->med_errno)) != NULL)
95 return (emsg);
96 (void) sprintf(p,
97 "unknown mediator errno %d\n", medep->med_errno);
98 return (buf);
99 } else {
100 if ((emsg = strerror(medep->med_errno)) != NULL)
101 return (emsg);
102 (void) sprintf(p,
103 "errno %d out of range", medep->med_errno);
104 return (buf);
105 }
106 }
107
108 /*
109 * printf-like log
110 */
111 static void
med_vprintf(const char * fmt,va_list ap)112 med_vprintf(
113 const char *fmt,
114 va_list ap
115 )
116 {
117 if (isatty(fileno(stderr))) {
118 #ifdef _REENTRANT
119 static mutex_t stderr_mx = DEFAULTMUTEX;
120
121 med_mx_lock(&stderr_mx);
122 #endif /* _REENTRANT */
123 (void) vfprintf(stderr, fmt, ap);
124 (void) fflush(stderr);
125 (void) fsync(fileno(stderr));
126 #ifdef _REENTRANT
127 med_mx_unlock(&stderr_mx);
128 #endif /* _REENTRANT */
129 }
130 vsyslog(LOG_ERR, fmt, ap);
131 }
132
133 /*PRINTFLIKE1*/
134 void
med_eprintf(const char * fmt,...)135 med_eprintf(
136 const char *fmt,
137 ...
138 )
139 {
140 va_list ap;
141
142 va_start(ap, fmt);
143 med_vprintf(fmt, ap);
144 va_end(ap);
145 }
146
147 /*
148 * printf-like perror() log
149 */
150 /*PRINTFLIKE2*/
151 static void
med_vperror(med_err_t * medep,const char * fmt,va_list ap)152 med_vperror(
153 med_err_t *medep,
154 const char *fmt,
155 va_list ap
156 )
157 {
158 char buf[1024];
159 char *p = buf;
160 size_t len = sizeof (buf);
161 int n;
162
163 if ((medep->med_node != NULL) && (medep->med_node[0] != '\0')) {
164 n = snprintf(p, len, "%s: ", medep->med_node);
165 p += n;
166 len -= n;
167 }
168 if ((medep->med_misc != NULL) && (medep->med_misc[0] != '\0')) {
169 n = snprintf(p, len, "%s: ", medep->med_misc);
170 p += n;
171 len -= n;
172 }
173 if ((fmt != NULL) && (*fmt != '\0')) {
174 n = vsnprintf(p, len, fmt, ap);
175 p += n;
176 len -= n;
177 n = snprintf(p, len, ": ");
178 p += n;
179 len -= n;
180 }
181 (void) snprintf(p, len, "%s", med_strerror(medep));
182 med_eprintf("%s\n", buf);
183 }
184
185 /*PRINTFLIKE2*/
186 void
medde_perror(med_err_t * medep,const char * fmt,...)187 medde_perror(
188 med_err_t *medep,
189 const char *fmt,
190 ...
191 )
192 {
193 va_list ap;
194
195 va_start(ap, fmt);
196 med_vperror(medep, fmt, ap);
197 va_end(ap);
198 }
199
200 /*PRINTFLIKE1*/
201 void
med_perror(const char * fmt,...)202 med_perror(
203 const char *fmt,
204 ...
205 )
206 {
207 va_list ap;
208 med_err_t status = med_null_err;
209
210 (void) med_error(&status, errno, NULL);
211 va_start(ap, fmt);
212 med_vperror(&status, fmt, ap);
213 va_end(ap);
214 med_clrerror(&status);
215 }
216