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 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 /* 27 * Copyright 2015 Joyent, Inc. 28 */ 29 30 #pragma weak _bindtextdomain = bindtextdomain 31 #pragma weak _textdomain = textdomain 32 #pragma weak _gettext = gettext 33 #pragma weak _dgettext = dgettext 34 #pragma weak _dcgettext = dcgettext 35 #pragma weak _ngettext = ngettext 36 #pragma weak _dngettext = dngettext 37 #pragma weak _dcngettext = dcngettext 38 #pragma weak _bind_textdomain_codeset = bind_textdomain_codeset 39 40 #include "lint.h" 41 #include "mtlib.h" 42 #include <errno.h> 43 #include <ctype.h> 44 #include <locale.h> 45 #include <stdio.h> 46 #include <stdlib.h> 47 #include <sys/types.h> 48 #include <sys/param.h> 49 #include <libintl.h> 50 #include <thread.h> 51 #include <synch.h> 52 #include "libc.h" 53 #include "_loc_path.h" 54 #include "msgfmt.h" 55 #include "gettext.h" 56 57 #define INIT_GT(def) \ 58 if (!global_gt) { \ 59 global_gt = (Gettext_t *)calloc(1, sizeof (Gettext_t)); \ 60 if (global_gt) \ 61 global_gt->cur_domain = (char *)default_domain; \ 62 else { \ 63 callout_lock_exit(); \ 64 return ((def)); \ 65 } \ 66 } 67 68 const char *defaultbind = DEFAULT_BINDING; 69 const char default_domain[] = DEFAULT_DOMAIN; 70 Gettext_t *global_gt = NULL; 71 72 char * 73 bindtextdomain(const char *domain, const char *binding) 74 { 75 char *res; 76 77 callout_lock_enter(); 78 INIT_GT(NULL); 79 res = _real_bindtextdomain_u(domain, binding, TP_BINDING); 80 callout_lock_exit(); 81 return (res); 82 } 83 84 char * 85 bind_textdomain_codeset(const char *domain, const char *codeset) 86 { 87 char *res; 88 89 callout_lock_enter(); 90 INIT_GT(NULL); 91 res = _real_bindtextdomain_u(domain, codeset, TP_CODESET); 92 callout_lock_exit(); 93 return (res); 94 } 95 96 /* 97 * textdomain() sets or queries the name of the current domain of 98 * the active LC_MESSAGES locale category. 99 */ 100 char * 101 textdomain(const char *domain) 102 { 103 char *res; 104 char tmp_domain[TEXTDOMAINMAX + 1]; 105 106 callout_lock_enter(); 107 INIT_GT(NULL); 108 res = _textdomain_u(domain, tmp_domain); 109 if (res == NULL) { 110 callout_lock_exit(); 111 return (NULL); 112 } 113 callout_lock_exit(); 114 return (CURRENT_DOMAIN(global_gt)); 115 } 116 117 /* 118 * gettext() is a pass-thru to _real_gettext_u() with a NULL pointer passed 119 * for domain and LC_MESSAGES passed for category. 120 */ 121 char * 122 gettext(const char *msg_id) 123 { 124 char *res; 125 int errno_save = errno; 126 127 callout_lock_enter(); 128 INIT_GT((char *)msg_id); 129 res = _real_gettext_u(NULL, msg_id, NULL, 0, LC_MESSAGES, 0, NULL); 130 callout_lock_exit(); 131 errno = errno_save; 132 return (res); 133 } 134 135 136 /* 137 * In dcgettext() call, domain is valid only for this call. 138 */ 139 char * 140 dgettext(const char *domain, const char *msg_id) 141 { 142 char *res; 143 int errno_save = errno; 144 145 callout_lock_enter(); 146 INIT_GT((char *)msg_id); 147 res = _real_gettext_u(domain, msg_id, NULL, 0, LC_MESSAGES, 0, NULL); 148 callout_lock_exit(); 149 errno = errno_save; 150 return (res); 151 } 152 153 char * 154 dgettext_l(const char *domain, const char *msg_id, locale_t loc) 155 { 156 char *res; 157 int errno_save = errno; 158 159 callout_lock_enter(); 160 INIT_GT((char *)msg_id); 161 res = _real_gettext_u(domain, msg_id, NULL, 0, LC_MESSAGES, 0, loc); 162 callout_lock_exit(); 163 errno = errno_save; 164 return (res); 165 } 166 167 char * 168 dcgettext(const char *domain, const char *msg_id, const int category) 169 { 170 char *res; 171 int errno_save = errno; 172 173 callout_lock_enter(); 174 INIT_GT((char *)msg_id); 175 res = _real_gettext_u(domain, msg_id, NULL, 0, category, 0, NULL); 176 callout_lock_exit(); 177 errno = errno_save; 178 return (res); 179 } 180 181 char * 182 ngettext(const char *msgid1, const char *msgid2, unsigned long int n) 183 { 184 char *res; 185 int errno_save = errno; 186 187 callout_lock_enter(); 188 INIT_GT((char *)msgid1); 189 res = _real_gettext_u(NULL, msgid1, msgid2, n, LC_MESSAGES, 1, NULL); 190 callout_lock_exit(); 191 errno = errno_save; 192 return (res); 193 } 194 195 char * 196 dngettext(const char *domain, const char *msgid1, const char *msgid2, 197 unsigned long int n) 198 { 199 char *res; 200 int errno_save = errno; 201 202 callout_lock_enter(); 203 INIT_GT((char *)msgid1); 204 res = _real_gettext_u(domain, msgid1, msgid2, n, LC_MESSAGES, 1, NULL); 205 callout_lock_exit(); 206 errno = errno_save; 207 return (res); 208 } 209 210 char * 211 dcngettext(const char *domain, const char *msgid1, const char *msgid2, 212 unsigned long int n, int category) 213 { 214 char *res; 215 int errno_save = errno; 216 217 callout_lock_enter(); 218 INIT_GT((char *)msgid1); 219 res = _real_gettext_u(domain, msgid1, msgid2, n, category, 1, NULL); 220 callout_lock_exit(); 221 errno = errno_save; 222 return (res); 223 } 224