Deleted Added
full compact
uu_misc.c (225736) uu_misc.c (243674)
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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26#include "libuutil_common.h"
27
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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26#include "libuutil_common.h"
27
28#define HAVE_ASSFAIL 1
29
28#include <assert.h>
29#include <errno.h>
30#include <libintl.h>
31#include <pthread.h>
32#include <stdarg.h>
33#include <stdio.h>
34#include <stdlib.h>
35#include <string.h>
36#include <sys/debug.h>
37#include <thread.h>
38#include <unistd.h>
39#include <ctype.h>
40
41#if !defined(TEXT_DOMAIN)
42#define TEXT_DOMAIN "SYS_TEST"
43#endif
44
45/*
46 * All of the old code under !defined(PTHREAD_ONCE_KEY_NP)
47 * is here to enable the building of a native version of
48 * libuutil.so when the build machine has not yet been upgraded
49 * to a version of libc that provides pthread_key_create_once_np().
50 * It should all be deleted when solaris_nevada ships.
51 * The code is not MT-safe in a relaxed memory model.
52 */
53
54#if defined(PTHREAD_ONCE_KEY_NP)
55static pthread_key_t uu_error_key = PTHREAD_ONCE_KEY_NP;
56#else /* PTHREAD_ONCE_KEY_NP */
57static pthread_key_t uu_error_key = 0;
58static pthread_mutex_t uu_key_lock = PTHREAD_MUTEX_INITIALIZER;
59#endif /* PTHREAD_ONCE_KEY_NP */
60
61static int uu_error_key_setup = 0;
62
63static pthread_mutex_t uu_panic_lock = PTHREAD_MUTEX_INITIALIZER;
64/* LINTED static unused */
65static const char *uu_panic_format;
66/* LINTED static unused */
67static va_list uu_panic_args;
68static pthread_t uu_panic_thread;
69
70static uint32_t _uu_main_error;
71
72void
73uu_set_error(uint_t code)
74{
75
76#if defined(PTHREAD_ONCE_KEY_NP)
77 if (pthread_key_create_once_np(&uu_error_key, NULL) != 0)
78 uu_error_key_setup = -1;
79 else
80 uu_error_key_setup = 1;
81#else /* PTHREAD_ONCE_KEY_NP */
82 if (uu_error_key_setup == 0) {
83 (void) pthread_mutex_lock(&uu_key_lock);
84 if (uu_error_key_setup == 0) {
85 if (pthread_key_create(&uu_error_key, NULL) != 0)
86 uu_error_key_setup = -1;
87 else
88 uu_error_key_setup = 1;
89 }
90 (void) pthread_mutex_unlock(&uu_key_lock);
91 }
92#endif /* PTHREAD_ONCE_KEY_NP */
93 if (uu_error_key_setup > 0)
94 (void) pthread_setspecific(uu_error_key,
95 (void *)(uintptr_t)code);
96}
97
98uint32_t
99uu_error(void)
100{
101
102 if (uu_error_key_setup < 0) /* can't happen? */
103 return (UU_ERROR_UNKNOWN);
104
105 /*
106 * Because UU_ERROR_NONE == 0, if uu_set_error() was
107 * never called, then this will return UU_ERROR_NONE:
108 */
109 return ((uint32_t)(uintptr_t)pthread_getspecific(uu_error_key));
110}
111
112const char *
113uu_strerror(uint32_t code)
114{
115 const char *str;
116
117 switch (code) {
118 case UU_ERROR_NONE:
119 str = dgettext(TEXT_DOMAIN, "No error");
120 break;
121
122 case UU_ERROR_INVALID_ARGUMENT:
123 str = dgettext(TEXT_DOMAIN, "Invalid argument");
124 break;
125
126 case UU_ERROR_UNKNOWN_FLAG:
127 str = dgettext(TEXT_DOMAIN, "Unknown flag passed");
128 break;
129
130 case UU_ERROR_NO_MEMORY:
131 str = dgettext(TEXT_DOMAIN, "Out of memory");
132 break;
133
134 case UU_ERROR_CALLBACK_FAILED:
135 str = dgettext(TEXT_DOMAIN, "Callback-initiated failure");
136 break;
137
138 case UU_ERROR_NOT_SUPPORTED:
139 str = dgettext(TEXT_DOMAIN, "Operation not supported");
140 break;
141
142 case UU_ERROR_EMPTY:
143 str = dgettext(TEXT_DOMAIN, "No value provided");
144 break;
145
146 case UU_ERROR_UNDERFLOW:
147 str = dgettext(TEXT_DOMAIN, "Value too small");
148 break;
149
150 case UU_ERROR_OVERFLOW:
151 str = dgettext(TEXT_DOMAIN, "Value too large");
152 break;
153
154 case UU_ERROR_INVALID_CHAR:
155 str = dgettext(TEXT_DOMAIN,
156 "Value contains unexpected character");
157 break;
158
159 case UU_ERROR_INVALID_DIGIT:
160 str = dgettext(TEXT_DOMAIN,
161 "Value contains digit not in base");
162 break;
163
164 case UU_ERROR_SYSTEM:
165 str = dgettext(TEXT_DOMAIN, "Underlying system error");
166 break;
167
168 case UU_ERROR_UNKNOWN:
169 str = dgettext(TEXT_DOMAIN, "Error status not known");
170 break;
171
172 default:
173 errno = ESRCH;
174 str = NULL;
175 break;
176 }
177 return (str);
178}
179
180void
181uu_panic(const char *format, ...)
182{
183 va_list args;
184
185 va_start(args, format);
186
187 (void) pthread_mutex_lock(&uu_panic_lock);
188 if (uu_panic_thread == 0) {
189 uu_panic_thread = pthread_self();
190 uu_panic_format = format;
191 va_copy(uu_panic_args, args);
192 }
193 (void) pthread_mutex_unlock(&uu_panic_lock);
194
195 (void) vfprintf(stderr, format, args);
196
197 if (uu_panic_thread == pthread_self())
198 abort();
199 else
200 for (;;)
201 (void) pause();
202}
203
204int
205assfail(const char *astring, const char *file, int line)
206{
207 __assert(astring, file, line);
208 /*NOTREACHED*/
209 return (0);
210}
211
212static void
213uu_lockup(void)
214{
215 (void) pthread_mutex_lock(&uu_panic_lock);
216#if !defined(PTHREAD_ONCE_KEY_NP)
217 (void) pthread_mutex_lock(&uu_key_lock);
218#endif
219 uu_avl_lockup();
220 uu_list_lockup();
221}
222
223static void
224uu_release(void)
225{
226 (void) pthread_mutex_unlock(&uu_panic_lock);
227#if !defined(PTHREAD_ONCE_KEY_NP)
228 (void) pthread_mutex_unlock(&uu_key_lock);
229#endif
230 uu_avl_release();
231 uu_list_release();
232}
233
234static void
235uu_release_child(void)
236{
237 uu_panic_format = NULL;
238 uu_panic_thread = 0;
239
240 uu_release();
241}
242
243#pragma init(uu_init)
244static void
245uu_init(void)
246{
247 (void) pthread_atfork(uu_lockup, uu_release, uu_release_child);
248}
249
250/*
251 * Dump a block of memory in hex+ascii, for debugging
252 */
253void
254uu_dump(FILE *out, const char *prefix, const void *buf, size_t len)
255{
256 const unsigned char *p = buf;
257 int i;
258
259 for (i = 0; i < len; i += 16) {
260 int j;
261
262 (void) fprintf(out, "%s", prefix);
263 for (j = 0; j < 16 && i + j < len; j++) {
264 (void) fprintf(out, "%2.2x ", p[i + j]);
265 }
266 for (; j < 16; j++) {
267 (void) fprintf(out, " ");
268 }
269 for (j = 0; j < 16 && i + j < len; j++) {
270 (void) fprintf(out, "%c",
271 isprint(p[i + j]) ? p[i + j] : '.');
272 }
273 (void) fprintf(out, "\n");
274 }
275}
30#include <assert.h>
31#include <errno.h>
32#include <libintl.h>
33#include <pthread.h>
34#include <stdarg.h>
35#include <stdio.h>
36#include <stdlib.h>
37#include <string.h>
38#include <sys/debug.h>
39#include <thread.h>
40#include <unistd.h>
41#include <ctype.h>
42
43#if !defined(TEXT_DOMAIN)
44#define TEXT_DOMAIN "SYS_TEST"
45#endif
46
47/*
48 * All of the old code under !defined(PTHREAD_ONCE_KEY_NP)
49 * is here to enable the building of a native version of
50 * libuutil.so when the build machine has not yet been upgraded
51 * to a version of libc that provides pthread_key_create_once_np().
52 * It should all be deleted when solaris_nevada ships.
53 * The code is not MT-safe in a relaxed memory model.
54 */
55
56#if defined(PTHREAD_ONCE_KEY_NP)
57static pthread_key_t uu_error_key = PTHREAD_ONCE_KEY_NP;
58#else /* PTHREAD_ONCE_KEY_NP */
59static pthread_key_t uu_error_key = 0;
60static pthread_mutex_t uu_key_lock = PTHREAD_MUTEX_INITIALIZER;
61#endif /* PTHREAD_ONCE_KEY_NP */
62
63static int uu_error_key_setup = 0;
64
65static pthread_mutex_t uu_panic_lock = PTHREAD_MUTEX_INITIALIZER;
66/* LINTED static unused */
67static const char *uu_panic_format;
68/* LINTED static unused */
69static va_list uu_panic_args;
70static pthread_t uu_panic_thread;
71
72static uint32_t _uu_main_error;
73
74void
75uu_set_error(uint_t code)
76{
77
78#if defined(PTHREAD_ONCE_KEY_NP)
79 if (pthread_key_create_once_np(&uu_error_key, NULL) != 0)
80 uu_error_key_setup = -1;
81 else
82 uu_error_key_setup = 1;
83#else /* PTHREAD_ONCE_KEY_NP */
84 if (uu_error_key_setup == 0) {
85 (void) pthread_mutex_lock(&uu_key_lock);
86 if (uu_error_key_setup == 0) {
87 if (pthread_key_create(&uu_error_key, NULL) != 0)
88 uu_error_key_setup = -1;
89 else
90 uu_error_key_setup = 1;
91 }
92 (void) pthread_mutex_unlock(&uu_key_lock);
93 }
94#endif /* PTHREAD_ONCE_KEY_NP */
95 if (uu_error_key_setup > 0)
96 (void) pthread_setspecific(uu_error_key,
97 (void *)(uintptr_t)code);
98}
99
100uint32_t
101uu_error(void)
102{
103
104 if (uu_error_key_setup < 0) /* can't happen? */
105 return (UU_ERROR_UNKNOWN);
106
107 /*
108 * Because UU_ERROR_NONE == 0, if uu_set_error() was
109 * never called, then this will return UU_ERROR_NONE:
110 */
111 return ((uint32_t)(uintptr_t)pthread_getspecific(uu_error_key));
112}
113
114const char *
115uu_strerror(uint32_t code)
116{
117 const char *str;
118
119 switch (code) {
120 case UU_ERROR_NONE:
121 str = dgettext(TEXT_DOMAIN, "No error");
122 break;
123
124 case UU_ERROR_INVALID_ARGUMENT:
125 str = dgettext(TEXT_DOMAIN, "Invalid argument");
126 break;
127
128 case UU_ERROR_UNKNOWN_FLAG:
129 str = dgettext(TEXT_DOMAIN, "Unknown flag passed");
130 break;
131
132 case UU_ERROR_NO_MEMORY:
133 str = dgettext(TEXT_DOMAIN, "Out of memory");
134 break;
135
136 case UU_ERROR_CALLBACK_FAILED:
137 str = dgettext(TEXT_DOMAIN, "Callback-initiated failure");
138 break;
139
140 case UU_ERROR_NOT_SUPPORTED:
141 str = dgettext(TEXT_DOMAIN, "Operation not supported");
142 break;
143
144 case UU_ERROR_EMPTY:
145 str = dgettext(TEXT_DOMAIN, "No value provided");
146 break;
147
148 case UU_ERROR_UNDERFLOW:
149 str = dgettext(TEXT_DOMAIN, "Value too small");
150 break;
151
152 case UU_ERROR_OVERFLOW:
153 str = dgettext(TEXT_DOMAIN, "Value too large");
154 break;
155
156 case UU_ERROR_INVALID_CHAR:
157 str = dgettext(TEXT_DOMAIN,
158 "Value contains unexpected character");
159 break;
160
161 case UU_ERROR_INVALID_DIGIT:
162 str = dgettext(TEXT_DOMAIN,
163 "Value contains digit not in base");
164 break;
165
166 case UU_ERROR_SYSTEM:
167 str = dgettext(TEXT_DOMAIN, "Underlying system error");
168 break;
169
170 case UU_ERROR_UNKNOWN:
171 str = dgettext(TEXT_DOMAIN, "Error status not known");
172 break;
173
174 default:
175 errno = ESRCH;
176 str = NULL;
177 break;
178 }
179 return (str);
180}
181
182void
183uu_panic(const char *format, ...)
184{
185 va_list args;
186
187 va_start(args, format);
188
189 (void) pthread_mutex_lock(&uu_panic_lock);
190 if (uu_panic_thread == 0) {
191 uu_panic_thread = pthread_self();
192 uu_panic_format = format;
193 va_copy(uu_panic_args, args);
194 }
195 (void) pthread_mutex_unlock(&uu_panic_lock);
196
197 (void) vfprintf(stderr, format, args);
198
199 if (uu_panic_thread == pthread_self())
200 abort();
201 else
202 for (;;)
203 (void) pause();
204}
205
206int
207assfail(const char *astring, const char *file, int line)
208{
209 __assert(astring, file, line);
210 /*NOTREACHED*/
211 return (0);
212}
213
214static void
215uu_lockup(void)
216{
217 (void) pthread_mutex_lock(&uu_panic_lock);
218#if !defined(PTHREAD_ONCE_KEY_NP)
219 (void) pthread_mutex_lock(&uu_key_lock);
220#endif
221 uu_avl_lockup();
222 uu_list_lockup();
223}
224
225static void
226uu_release(void)
227{
228 (void) pthread_mutex_unlock(&uu_panic_lock);
229#if !defined(PTHREAD_ONCE_KEY_NP)
230 (void) pthread_mutex_unlock(&uu_key_lock);
231#endif
232 uu_avl_release();
233 uu_list_release();
234}
235
236static void
237uu_release_child(void)
238{
239 uu_panic_format = NULL;
240 uu_panic_thread = 0;
241
242 uu_release();
243}
244
245#pragma init(uu_init)
246static void
247uu_init(void)
248{
249 (void) pthread_atfork(uu_lockup, uu_release, uu_release_child);
250}
251
252/*
253 * Dump a block of memory in hex+ascii, for debugging
254 */
255void
256uu_dump(FILE *out, const char *prefix, const void *buf, size_t len)
257{
258 const unsigned char *p = buf;
259 int i;
260
261 for (i = 0; i < len; i += 16) {
262 int j;
263
264 (void) fprintf(out, "%s", prefix);
265 for (j = 0; j < 16 && i + j < len; j++) {
266 (void) fprintf(out, "%2.2x ", p[i + j]);
267 }
268 for (; j < 16; j++) {
269 (void) fprintf(out, " ");
270 }
271 for (j = 0; j < 16 && i + j < len; j++) {
272 (void) fprintf(out, "%c",
273 isprint(p[i + j]) ? p[i + j] : '.');
274 }
275 (void) fprintf(out, "\n");
276 }
277}