src/solaris/native/java/lang/java_props_md.c
author ohair
Fri Jan 30 16:27:33 2009 -0800 (3 years ago)
changeset 9 2d585507a41b
parent 239e8fe7a0af1
child 354ffa98eed5766
permissions -rw-r--r--
6755905: Changes for openjdk6 build 04
6628175: NetBeans/OpenJDK projects should support generated sources
6598089: JDK 7: AWT often goes into busy loop when showing dialog
6612531: api/javax_swing/ScrollPaneLayout/index.html#xxxLayoutSize[ScrollPaneLayout2024] throws NPE
6550267: Debugging some NetBeans/OpenJDK project's demo apps does not work
6610014: Allow partial open jdk builds without access to binary plugs
6643627: JMX source code includes incorrect Java code
6652042: NetBeans JConsole project should run tests against JAR built by project
6652053: Rename NetBeans project from j2se to jdk
6653678: NetBeans JDK projects README file should be release-agnostic
6654456: OpenJDK build problem with freetype makefiles
6654903: OpenJDK NetBeans projects should ony run appropriate tests
6658909: A few more SCCS keyword cleanups and whitespace processing
6616089: Whitespace cleanup on all sources
Summary: Final b04 state (as defined by the source bundle)
Reviewed-by: darcy
        1 /*
        2  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
        3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        4  *
        5  * This code is free software; you can redistribute it and/or modify it
        6  * under the terms of the GNU General Public License version 2 only, as
        7  * published by the Free Software Foundation.  Sun designates this
        8  * particular file as subject to the "Classpath" exception as provided
        9  * by Sun in the LICENSE file that accompanied this code.
       10  *
       11  * This code is distributed in the hope that it will be useful, but WITHOUT
       12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       14  * version 2 for more details (a copy is included in the LICENSE file that
       15  * accompanied this code).
       16  *
       17  * You should have received a copy of the GNU General Public License version
       18  * 2 along with this work; if not, write to the Free Software Foundation,
       19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       20  *
       21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       22  * CA 95054 USA or visit www.sun.com if you need additional information or
       23  * have any questions.
       24  */
       25 
       26 #ifdef __linux__
       27 #include <stdio.h>
       28 #include <ctype.h>
       29 #endif
       30 #include <pwd.h>
       31 #include <locale.h>
       32 #ifndef ARCHPROPNAME
       33 #error "The macro ARCHPROPNAME has not been defined"
       34 #endif
       35 #include <sys/utsname.h>        /* For os_name and os_version */
       36 #include <langinfo.h>           /* For nl_langinfo */
       37 #include <stdlib.h>
       38 #include <string.h>
       39 #include <sys/types.h>
       40 #include <unistd.h>
       41 #include <sys/param.h>
       42 #include <time.h>
       43 #include <errno.h>
       44 
       45 #include "locale_str.h"
       46 #include "java_props.h"
       47 
       48 #ifdef __linux__
       49 #define CODESET _NL_CTYPE_CODESET_NAME
       50 #else
       51 #ifdef ALT_CODESET_KEY
       52 #define CODESET ALT_CODESET_KEY
       53 #endif
       54 #endif
       55 
       56 /* Take an array of string pairs (map of key->value) and a string (key).
       57  * Examine each pair in the map to see if the first string (key) matches the
       58  * string.  If so, store the second string of the pair (value) in the value and
       59  * return 1.  Otherwise do nothing and return 0.  The end of the map is
       60  * indicated by an empty string at the start of a pair (key of "").
       61  */
       62 static int
       63 mapLookup(char* map[], const char* key, char** value) {
       64     int i;
       65     for (i = 0; strcmp(map[i], ""); i += 2){
       66         if (!strcmp(key, map[i])){
       67             *value = map[i + 1];
       68             return 1;
       69         }
       70     }
       71     return 0;
       72 }
       73 
       74 /* This function sets an environment variable using envstring.
       75  * The format of envstring is "name=value".
       76  * If the name has already existed, it will append value to the name.
       77  */
       78 static void
       79 setPathEnvironment(char *envstring)
       80 {
       81     char name[20], *value, *current;
       82 
       83     value = strchr(envstring, '='); /* locate name and value separator */
       84 
       85     if (! value)
       86         return; /* not a valid environment setting */
       87 
       88     /* copy first part as environment name */
       89     strncpy(name, envstring, value - envstring);
       90     name[value-envstring] = '\0';
       91 
       92     value++; /* set value point to value of the envstring */
       93 
       94     current = getenv(name);
       95     if (current) {
       96         if (! strstr(current, value)) {
       97             /* value is not found in current environment, append it */
       98             char *temp = malloc(strlen(envstring) + strlen(current) + 2);
       99         strcpy(temp, name);
      100         strcat(temp, "=");
      101         strcat(temp, current);
      102         strcat(temp, ":");
      103         strcat(temp, value);
      104         putenv(temp);
      105         }
      106         /* else the value has already been set, do nothing */
      107     }
      108     else {
      109         /* environment variable is not found */
      110         putenv(envstring);
      111     }
      112 }
      113 
      114 #ifndef P_tmpdir
      115 #define P_tmpdir "/var/tmp"
      116 #endif
      117 
      118 /* This function gets called very early, before VM_CALLS are setup.
      119  * Do not use any of the VM_CALLS entries!!!
      120  */
      121 java_props_t *
      122 GetJavaProperties(JNIEnv *env)
      123 {
      124     static java_props_t sprops = {0};
      125     char *v; /* tmp var */
      126 
      127     if (sprops.user_dir) {
      128         return &sprops;
      129     }
      130 
      131     /* tmp dir */
      132     sprops.tmp_dir = P_tmpdir;
      133 
      134     /* Printing properties */
      135     sprops.printerJob = "sun.print.PSPrinterJob";
      136 
      137     /* patches/service packs installed */
      138     sprops.patch_level = "unknown";
      139 
      140     /* Java 2D properties */
      141     sprops.graphics_env = "sun.awt.X11GraphicsEnvironment";
      142     sprops.awt_toolkit = NULL;
      143 
      144     /* This is used only for debugging of font problems. */
      145     v = getenv("JAVA2D_FONTPATH");
      146     sprops.font_dir = v ? v : NULL;
      147 
      148 #ifdef SI_ISALIST
      149     /* supported instruction sets */
      150     {
      151         char list[258];
      152         sysinfo(SI_ISALIST, list, sizeof(list));
      153         sprops.cpu_isalist = strdup(list);
      154     }
      155 #else
      156     sprops.cpu_isalist = NULL;
      157 #endif
      158 
      159     /* endianness of platform */
      160     {
      161         unsigned int endianTest = 0xff000000;
      162         if (((char*)(&endianTest))[0] != 0)
      163             sprops.cpu_endian = "big";
      164         else
      165             sprops.cpu_endian = "little";
      166     }
      167 
      168     /* os properties */
      169     {
      170         struct utsname name;
      171         uname(&name);
      172         sprops.os_name = strdup(name.sysname);
      173         sprops.os_version = strdup(name.release);
      174 
      175         sprops.os_arch = ARCHPROPNAME;
      176 
      177         if (getenv("GNOME_DESKTOP_SESSION_ID") != NULL) {
      178             sprops.desktop = "gnome";
      179         }
      180         else {
      181             sprops.desktop = NULL;
      182         }
      183     }
      184 
      185     /* Determine the language, country, variant, and encoding from the host,
      186      * and store these in the user.language, user.country, user.variant and
      187      * file.encoding system properties. */
      188     {
      189         char *lc;
      190         lc = setlocale(LC_CTYPE, "");
      191 #ifndef __linux__
      192         if (lc == NULL) {
      193             /*
      194              * 'lc == null' means system doesn't support user's environment
      195              * variable's locale.
      196              */
      197           setlocale(LC_ALL, "C");
      198           sprops.language = "en";
      199           sprops.encoding = "ISO8859-1";
      200           sprops.sun_jnu_encoding = sprops.encoding;
      201         } else {
      202 #else
      203         if (lc == NULL || !strcmp(lc, "C") || !strcmp(lc, "POSIX")) {
      204             lc = "en_US";
      205         }
      206         {
      207 #endif
      208 
      209             /*
      210              * locale string format in Solaris is
      211              * <language name>_<country name>.<encoding name>@<variant name>
      212              * <country name>, <encoding name>, and <variant name> are optional.
      213              */
      214             char temp[64];
      215             char *language = NULL, *country = NULL, *variant = NULL,
      216                  *encoding = NULL;
      217             char *std_language = NULL, *std_country = NULL, *std_variant = NULL,
      218                  *std_encoding = NULL;
      219             char *p, encoding_variant[64];
      220             int i, found;
      221 
      222 #ifndef __linux__
      223             /*
      224              * Workaround for Solaris bug 4201684: Xlib doesn't like @euro
      225              * locales. Since we don't depend on the libc @euro behavior,
      226              * we just remove the qualifier.
      227              * On Linux, the bug doesn't occur; on the other hand, @euro
      228              * is needed there because it's a shortcut that also determines
      229              * the encoding - without it, we wouldn't get ISO-8859-15.
      230              * Therefore, this code section is Solaris-specific.
      231              */
      232             lc = strdup(lc);    /* keep a copy, setlocale trashes original. */
      233             strcpy(temp, lc);
      234             p = strstr(temp, "@euro");
      235             if (p != NULL)
      236                 *p = '\0';
      237             setlocale(LC_ALL, temp);
      238 #endif
      239 
      240             strcpy(temp, lc);
      241 
      242             /* Parse the language, country, encoding, and variant from the
      243              * locale.  Any of the elements may be missing, but they must occur
      244              * in the order language_country.encoding@variant, and must be
      245              * preceded by their delimiter (except for language).
      246              *
      247              * If the locale name (without .encoding@variant, if any) matches
      248              * any of the names in the locale_aliases list, map it to the
      249              * corresponding full locale name.  Most of the entries in the
      250              * locale_aliases list are locales that include a language name but
      251              * no country name, and this facility is used to map each language
      252              * to a default country if that's possible.  It's also used to map
      253              * the Solaris locale aliases to their proper Java locale IDs.
      254              */
      255             if ((p = strchr(temp, '.')) != NULL) {
      256                 strcpy(encoding_variant, p); /* Copy the leading '.' */
      257                 *p = '\0';
      258             } else if ((p = strchr(temp, '@')) != NULL) {
      259                  strcpy(encoding_variant, p); /* Copy the leading '@' */
      260                  *p = '\0';
      261             } else {
      262                 *encoding_variant = '\0';
      263             }
      264 
      265             if (mapLookup(locale_aliases, temp, &p)) {
      266                 strcpy(temp, p);
      267             }
      268 
      269             language = temp;
      270             if ((country = strchr(temp, '_')) != NULL) {
      271                 *country++ = '\0';
      272             }
      273 
      274             p = encoding_variant;
      275             if ((encoding = strchr(p, '.')) != NULL) {
      276                 p[encoding++ - p] = '\0';
      277                 p = encoding;
      278             }
      279             if ((variant = strchr(p, '@')) != NULL) {
      280                 p[variant++ - p] = '\0';
      281             }
      282 
      283             /* Normalize the language name */
      284             std_language = "en";
      285             if (language != NULL) {
      286                 mapLookup(language_names, language, &std_language);
      287             }
      288             sprops.language = std_language;
      289 
      290             /* Normalize the country name */
      291             if (country != NULL) {
      292                 std_country = country;
      293                 mapLookup(country_names, country, &std_country);
      294                 sprops.country = strdup(std_country);
      295             }
      296 
      297             /* Normalize the variant name.  Note that we only use
      298              * variants listed in the mapping array; others are ignored. */
      299             if (variant != NULL) {
      300                 mapLookup(variant_names, variant, &std_variant);
      301                 sprops.variant = std_variant;
      302             }
      303 
      304             /* Normalize the encoding name.  Note that we IGNORE the string
      305              * 'encoding' extracted from the locale name above.  Instead, we use the
      306              * more reliable method of calling nl_langinfo(CODESET).  This function
      307              * returns an empty string if no encoding is set for the given locale
      308              * (e.g., the C or POSIX locales); we use the default ISO 8859-1
      309              * converter for such locales.
      310              */
      311 
      312             /* OK, not so reliable - nl_langinfo() gives wrong answers on
      313              * Euro locales, in particular. */
      314             if (strcmp(p, "ISO8859-15") == 0)
      315                 p = "ISO8859-15";
      316             else
      317                 p = nl_langinfo(CODESET);
      318 
      319             /* Convert the bare "646" used on Solaris to a proper IANA name */
      320             if (strcmp(p, "646") == 0)
      321                 p = "ISO646-US";
      322 
      323             /* return same result nl_langinfo would return for en_UK,
      324              * in order to use optimizations. */
      325             std_encoding = (*p != '\0') ? p : "ISO8859-1";
      326 
      327 
      328 #ifdef __linux__
      329             /*
      330              * Remap the encoding string to a different value for japanese
      331              * locales on linux so that customized converters are used instead
      332              * of the default converter for "EUC-JP". The customized converters
      333              * omit support for the JIS0212 encoding which is not supported by
      334              * the variant of "EUC-JP" encoding used on linux
      335              */
      336             if (strcmp(p, "EUC-JP") == 0) {
      337                 std_encoding = "EUC-JP-LINUX";
      338             }
      339 #else
      340             /* For Solaris use customized vendor defined character
      341              * customized EUC-JP converter
      342              */
      343             if (strcmp(p,"eucJP") == 0) {
      344                 std_encoding = "eucJP-open";
      345             }
      346 #endif
      347 #ifndef __linux__
      348             /*
      349              * Remap the encoding string to Big5_Solaris which augments
      350              * the default converter for Solaris Big5 locales to include
      351              * seven additional ideographic characters beyond those included
      352              * in the Java "Big5" converter.
      353              */
      354             if (strcmp(p, "Big5") == 0) {
      355                     std_encoding = "Big5_Solaris";
      356             }
      357 #endif
      358             sprops.encoding = std_encoding;
      359             sprops.sun_jnu_encoding = sprops.encoding;
      360         }
      361     }
      362 
      363 #ifdef __linux__
      364 #if __BYTE_ORDER == __LITTLE_ENDIAN
      365     sprops.unicode_encoding = "UnicodeLittle";
      366 #else
      367     sprops.unicode_encoding = "UnicodeBig";
      368 #endif
      369 #else
      370     sprops.unicode_encoding = "UnicodeBig";
      371 #endif
      372 
      373     /* user properties */
      374     {
      375         struct passwd *pwent = getpwuid(getuid());
      376         sprops.user_name = pwent ? strdup(pwent->pw_name) : "?";
      377         sprops.user_home = pwent ? strdup(pwent->pw_dir) : "?";
      378     }
      379 
      380     /* User TIMEZONE */
      381     {
      382         /*
      383          * We defer setting up timezone until it's actually necessary.
      384          * Refer to TimeZone.getDefault(). However, the system
      385          * property is necessary to be able to be set by the command
      386          * line interface -D. Here temporarily set a null string to
      387          * timezone.
      388          */
      389         tzset();        /* for compatibility */
      390         sprops.timezone = "";
      391     }
      392 
      393     /* Current directory */
      394     {
      395         char buf[MAXPATHLEN];
      396         errno = 0;
      397         if (getcwd(buf, sizeof(buf))  == NULL)
      398             JNU_ThrowByName(env, "java/lang/Error",
      399              "Properties init: Could not determine current working directory.");
      400         else
      401             sprops.user_dir = strdup(buf);
      402     }
      403 
      404     sprops.file_separator = "/";
      405     sprops.path_separator = ":";
      406     sprops.line_separator = "\n";
      407 
      408     /* Append CDE message and resource search path to NLSPATH and
      409      * XFILESEARCHPATH, in order to pick localized message for
      410      * FileSelectionDialog window (Bug 4173641).
      411      */
      412     setPathEnvironment("NLSPATH=/usr/dt/lib/nls/msg/%L/%N.cat");
      413     setPathEnvironment("XFILESEARCHPATH=/usr/dt/app-defaults/%L/Dt");
      414 
      415     return &sprops;
      416 }