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.
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.
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]
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include "libuutil_common.h"
39 #include <sys/debug.h>
43 #if !defined(TEXT_DOMAIN)
44 #define TEXT_DOMAIN "SYS_TEST"
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.
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 */
63 static int uu_error_key_setup
= 0;
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
;
72 static uint32_t _uu_main_error
;
75 uu_set_error(uint_t code
)
77 if (thr_main() != 0) {
78 _uu_main_error
= code
;
81 #if defined(PTHREAD_ONCE_KEY_NP)
82 if (pthread_key_create_once_np(&uu_error_key
, NULL
) != 0)
83 uu_error_key_setup
= -1;
85 uu_error_key_setup
= 1;
86 #else /* PTHREAD_ONCE_KEY_NP */
87 if (uu_error_key_setup
== 0) {
88 (void) pthread_mutex_lock(&uu_key_lock
);
89 if (uu_error_key_setup
== 0) {
90 if (pthread_key_create(&uu_error_key
, NULL
) != 0)
91 uu_error_key_setup
= -1;
93 uu_error_key_setup
= 1;
95 (void) pthread_mutex_unlock(&uu_key_lock
);
97 #endif /* PTHREAD_ONCE_KEY_NP */
98 if (uu_error_key_setup
> 0)
99 (void) pthread_setspecific(uu_error_key
,
100 (void *)(uintptr_t)code
);
107 return (_uu_main_error
);
109 if (uu_error_key_setup
< 0) /* can't happen? */
110 return (UU_ERROR_UNKNOWN
);
113 * Because UU_ERROR_NONE == 0, if uu_set_error() was
114 * never called, then this will return UU_ERROR_NONE:
116 return ((uint32_t)(uintptr_t)pthread_getspecific(uu_error_key
));
120 uu_strerror(uint32_t code
)
126 str
= dgettext(TEXT_DOMAIN
, "No error");
129 case UU_ERROR_INVALID_ARGUMENT
:
130 str
= dgettext(TEXT_DOMAIN
, "Invalid argument");
133 case UU_ERROR_UNKNOWN_FLAG
:
134 str
= dgettext(TEXT_DOMAIN
, "Unknown flag passed");
137 case UU_ERROR_NO_MEMORY
:
138 str
= dgettext(TEXT_DOMAIN
, "Out of memory");
141 case UU_ERROR_CALLBACK_FAILED
:
142 str
= dgettext(TEXT_DOMAIN
, "Callback-initiated failure");
145 case UU_ERROR_NOT_SUPPORTED
:
146 str
= dgettext(TEXT_DOMAIN
, "Operation not supported");
150 str
= dgettext(TEXT_DOMAIN
, "No value provided");
153 case UU_ERROR_UNDERFLOW
:
154 str
= dgettext(TEXT_DOMAIN
, "Value too small");
157 case UU_ERROR_OVERFLOW
:
158 str
= dgettext(TEXT_DOMAIN
, "Value too large");
161 case UU_ERROR_INVALID_CHAR
:
162 str
= dgettext(TEXT_DOMAIN
,
163 "Value contains unexpected character");
166 case UU_ERROR_INVALID_DIGIT
:
167 str
= dgettext(TEXT_DOMAIN
,
168 "Value contains digit not in base");
171 case UU_ERROR_SYSTEM
:
172 str
= dgettext(TEXT_DOMAIN
, "Underlying system error");
175 case UU_ERROR_UNKNOWN
:
176 str
= dgettext(TEXT_DOMAIN
, "Error status not known");
188 uu_panic(const char *format
, ...)
192 va_start(args
, format
);
194 (void) pthread_mutex_lock(&uu_panic_lock
);
195 if (uu_panic_thread
== 0) {
196 uu_panic_thread
= pthread_self();
197 uu_panic_format
= format
;
198 va_copy(uu_panic_args
, args
);
200 (void) pthread_mutex_unlock(&uu_panic_lock
);
202 (void) vfprintf(stderr
, format
, args
);
204 if (uu_panic_thread
== pthread_self())
212 assfail(const char *astring
, const char *file
, int line
)
214 __assert(astring
, file
, line
);
222 (void) pthread_mutex_lock(&uu_panic_lock
);
223 #if !defined(PTHREAD_ONCE_KEY_NP)
224 (void) pthread_mutex_lock(&uu_key_lock
);
233 (void) pthread_mutex_unlock(&uu_panic_lock
);
234 #if !defined(PTHREAD_ONCE_KEY_NP)
235 (void) pthread_mutex_unlock(&uu_key_lock
);
242 uu_release_child(void)
244 uu_panic_format
= NULL
;
250 #pragma init(uu_init)
254 (void) pthread_atfork(uu_lockup
, uu_release
, uu_release_child
);