ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/src/trunk/cddl/contrib/opensolaris/lib/libuutil/common/uu_misc.c
Revision: 1930
Committed: Wed Oct 15 18:56:14 2008 UTC (15 years, 6 months ago) by laffer1
Content type: text/plain
File size: 5669 byte(s)
Log Message:
Enter ZFS (userland)

File Contents

# Content
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 2007 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 "libuutil_common.h"
30
31 #include <assert.h>
32 #include <errno.h>
33 #include <libintl.h>
34 #include <pthread.h>
35 #include <stdarg.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <sys/debug.h>
40 #include <thread.h>
41 #include <unistd.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)
57 static pthread_key_t uu_error_key = PTHREAD_ONCE_KEY_NP;
58 #else /* PTHREAD_ONCE_KEY_NP */
59 static pthread_key_t uu_error_key = 0;
60 static pthread_mutex_t uu_key_lock = PTHREAD_MUTEX_INITIALIZER;
61 #endif /* PTHREAD_ONCE_KEY_NP */
62
63 static int uu_error_key_setup = 0;
64
65 static pthread_mutex_t uu_panic_lock = PTHREAD_MUTEX_INITIALIZER;
66 /* LINTED static unused */
67 static const char *uu_panic_format;
68 /* LINTED static unused */
69 static va_list uu_panic_args;
70 static pthread_t uu_panic_thread;
71
72 static uint32_t _uu_main_error;
73
74 void
75 uu_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
100 uint32_t
101 uu_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
114 const char *
115 uu_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
182 void
183 uu_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
206 int
207 assfail(const char *astring, const char *file, int line)
208 {
209 __assert(astring, file, line);
210 /*NOTREACHED*/
211 return (0);
212 }
213
214 static void
215 uu_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
225 static void
226 uu_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
236 static void
237 uu_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)
246 static void
247 uu_init(void)
248 {
249 (void) pthread_atfork(uu_lockup, uu_release, uu_release_child);
250 }

Properties

Name Value
cvs2svn:cvs-rev 1.1