The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/openzfs/lib/libuutil/uu_misc.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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 https://opensource.org/licenses/CDDL-1.0.
   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 #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 <unistd.h>
   38 #include <ctype.h>
   39 
   40 #if !defined(TEXT_DOMAIN)
   41 #define TEXT_DOMAIN "SYS_TEST"
   42 #endif
   43 
   44 /*
   45  * All of the old code under !defined(PTHREAD_ONCE_KEY_NP)
   46  * is here to enable the building of a native version of
   47  * libuutil.so when the build machine has not yet been upgraded
   48  * to a version of libc that provides pthread_key_create_once_np().
   49  * It should all be deleted when solaris_nevada ships.
   50  * The code is not MT-safe in a relaxed memory model.
   51  */
   52 
   53 #if defined(PTHREAD_ONCE_KEY_NP)
   54 static pthread_key_t    uu_error_key = PTHREAD_ONCE_KEY_NP;
   55 #else   /* PTHREAD_ONCE_KEY_NP */
   56 static pthread_key_t    uu_error_key = 0;
   57 static pthread_mutex_t  uu_key_lock = PTHREAD_MUTEX_INITIALIZER;
   58 #endif  /* PTHREAD_ONCE_KEY_NP */
   59 
   60 static int              uu_error_key_setup = 0;
   61 
   62 static pthread_mutex_t  uu_panic_lock = PTHREAD_MUTEX_INITIALIZER;
   63 /* LINTED static unused */
   64 static const char       *uu_panic_format;
   65 /* LINTED static unused */
   66 static va_list          uu_panic_args;
   67 static pthread_t        uu_panic_thread;
   68 
   69 static uint32_t         _uu_main_error;
   70 static __thread int     _uu_main_thread = 0;
   71 
   72 void
   73 uu_set_error(uint_t code)
   74 {
   75         if (_uu_main_thread) {
   76                 _uu_main_error = code;
   77                 return;
   78         }
   79 #if defined(PTHREAD_ONCE_KEY_NP)
   80         if (pthread_key_create_once_np(&uu_error_key, NULL) != 0)
   81                 uu_error_key_setup = -1;
   82         else
   83                 uu_error_key_setup = 1;
   84 #else   /* PTHREAD_ONCE_KEY_NP */
   85         if (uu_error_key_setup == 0) {
   86                 (void) pthread_mutex_lock(&uu_key_lock);
   87                 if (uu_error_key_setup == 0) {
   88                         if (pthread_key_create(&uu_error_key, NULL) != 0)
   89                                 uu_error_key_setup = -1;
   90                         else
   91                                 uu_error_key_setup = 1;
   92                 }
   93                 (void) pthread_mutex_unlock(&uu_key_lock);
   94         }
   95 #endif  /* PTHREAD_ONCE_KEY_NP */
   96         if (uu_error_key_setup > 0)
   97                 (void) pthread_setspecific(uu_error_key,
   98                     (void *)(uintptr_t)code);
   99 }
  100 
  101 uint32_t
  102 uu_error(void)
  103 {
  104         if (_uu_main_thread)
  105                 return (_uu_main_error);
  106 
  107         if (uu_error_key_setup < 0)     /* can't happen? */
  108                 return (UU_ERROR_UNKNOWN);
  109 
  110         /*
  111          * Because UU_ERROR_NONE == 0, if uu_set_error() was
  112          * never called, then this will return UU_ERROR_NONE:
  113          */
  114         return ((uint32_t)(uintptr_t)pthread_getspecific(uu_error_key));
  115 }
  116 
  117 const char *
  118 uu_strerror(uint32_t code)
  119 {
  120         const char *str;
  121 
  122         switch (code) {
  123         case UU_ERROR_NONE:
  124                 str = dgettext(TEXT_DOMAIN, "No error");
  125                 break;
  126 
  127         case UU_ERROR_INVALID_ARGUMENT:
  128                 str = dgettext(TEXT_DOMAIN, "Invalid argument");
  129                 break;
  130 
  131         case UU_ERROR_UNKNOWN_FLAG:
  132                 str = dgettext(TEXT_DOMAIN, "Unknown flag passed");
  133                 break;
  134 
  135         case UU_ERROR_NO_MEMORY:
  136                 str = dgettext(TEXT_DOMAIN, "Out of memory");
  137                 break;
  138 
  139         case UU_ERROR_CALLBACK_FAILED:
  140                 str = dgettext(TEXT_DOMAIN, "Callback-initiated failure");
  141                 break;
  142 
  143         case UU_ERROR_NOT_SUPPORTED:
  144                 str = dgettext(TEXT_DOMAIN, "Operation not supported");
  145                 break;
  146 
  147         case UU_ERROR_EMPTY:
  148                 str = dgettext(TEXT_DOMAIN, "No value provided");
  149                 break;
  150 
  151         case UU_ERROR_UNDERFLOW:
  152                 str = dgettext(TEXT_DOMAIN, "Value too small");
  153                 break;
  154 
  155         case UU_ERROR_OVERFLOW:
  156                 str = dgettext(TEXT_DOMAIN, "Value too large");
  157                 break;
  158 
  159         case UU_ERROR_INVALID_CHAR:
  160                 str = dgettext(TEXT_DOMAIN,
  161                     "Value contains unexpected character");
  162                 break;
  163 
  164         case UU_ERROR_INVALID_DIGIT:
  165                 str = dgettext(TEXT_DOMAIN,
  166                     "Value contains digit not in base");
  167                 break;
  168 
  169         case UU_ERROR_SYSTEM:
  170                 str = dgettext(TEXT_DOMAIN, "Underlying system error");
  171                 break;
  172 
  173         case UU_ERROR_UNKNOWN:
  174                 str = dgettext(TEXT_DOMAIN, "Error status not known");
  175                 break;
  176 
  177         default:
  178                 errno = ESRCH;
  179                 str = NULL;
  180                 break;
  181         }
  182         return (str);
  183 }
  184 
  185 void
  186 uu_panic(const char *format, ...)
  187 {
  188         va_list args;
  189 
  190         va_start(args, format);
  191 
  192         (void) pthread_mutex_lock(&uu_panic_lock);
  193         if (uu_panic_thread == 0) {
  194                 uu_panic_thread = pthread_self();
  195                 uu_panic_format = format;
  196                 va_copy(uu_panic_args, args);
  197         }
  198         (void) pthread_mutex_unlock(&uu_panic_lock);
  199 
  200         (void) vfprintf(stderr, format, args);
  201 
  202         va_end(args);
  203 
  204         if (uu_panic_thread == pthread_self())
  205                 abort();
  206         else
  207                 for (;;)
  208                         (void) pause();
  209 }
  210 
  211 static void
  212 uu_lockup(void)
  213 {
  214         (void) pthread_mutex_lock(&uu_panic_lock);
  215 #if !defined(PTHREAD_ONCE_KEY_NP)
  216         (void) pthread_mutex_lock(&uu_key_lock);
  217 #endif
  218         uu_avl_lockup();
  219         uu_list_lockup();
  220 }
  221 
  222 static void
  223 uu_release(void)
  224 {
  225         (void) pthread_mutex_unlock(&uu_panic_lock);
  226 #if !defined(PTHREAD_ONCE_KEY_NP)
  227         (void) pthread_mutex_unlock(&uu_key_lock);
  228 #endif
  229         uu_avl_release();
  230         uu_list_release();
  231 }
  232 
  233 static void
  234 uu_release_child(void)
  235 {
  236         uu_panic_format = NULL;
  237         uu_panic_thread = 0;
  238 
  239         uu_release();
  240 }
  241 
  242 #ifdef __GNUC__
  243 static void
  244 uu_init(void) __attribute__((constructor));
  245 #else
  246 #pragma init(uu_init)
  247 #endif
  248 
  249 static void
  250 uu_init(void)
  251 {
  252         _uu_main_thread = 1;
  253         (void) pthread_atfork(uu_lockup, uu_release, uu_release_child);
  254 }

Cache object: b462e89e72e2685e58fb7b088ad7509e


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.