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