Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/native/java/lang/java_props_md.c
32287 views
/*1* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#if defined(__linux__) || defined(_ALLBSD_SOURCE)26#include <stdio.h>27#include <ctype.h>28#endif29#include <pwd.h>30#include <locale.h>31#ifndef ARCHPROPNAME32#error "The macro ARCHPROPNAME has not been defined"33#endif34#include <sys/utsname.h> /* For os_name and os_version */35#ifndef __ANDROID__36# include <langinfo.h> /* For nl_langinfo */37#else38# include "langinfo.h"39#endif40#include <stdlib.h>41#include <string.h>42#include <sys/types.h>43#include <unistd.h>44#include <sys/param.h>45#include <time.h>46#include <errno.h>4748#ifdef MACOSX49#include "java_props_macosx.h"50#endif5152#if defined(_ALLBSD_SOURCE)53#if !defined(P_tmpdir)54#include <paths.h>55#define P_tmpdir _PATH_VARTMP56#endif57#endif5859#include "locale_str.h"60#include "java_props.h"6162#if !defined(_ALLBSD_SOURCE)63#ifdef __linux__64#ifndef CODESET65#define CODESET _NL_CTYPE_CODESET_NAME66#endif67#else68#ifdef ALT_CODESET_KEY69#define CODESET ALT_CODESET_KEY70#endif71#endif72#endif /* !_ALLBSD_SOURCE */7374#ifdef JAVASE_EMBEDDED75#include <dlfcn.h>76#include <sys/stat.h>77#endif7879/* Take an array of string pairs (map of key->value) and a string (key).80* Examine each pair in the map to see if the first string (key) matches the81* string. If so, store the second string of the pair (value) in the value and82* return 1. Otherwise do nothing and return 0. The end of the map is83* indicated by an empty string at the start of a pair (key of "").84*/85static int86mapLookup(char* map[], const char* key, char** value) {87int i;88for (i = 0; strcmp(map[i], ""); i += 2){89if (!strcmp(key, map[i])){90*value = map[i + 1];91return 1;92}93}94return 0;95}9697#ifndef P_tmpdir98#define P_tmpdir "/var/tmp"99#endif100101static int ParseLocale(JNIEnv* env, int cat, char ** std_language, char ** std_script,102char ** std_country, char ** std_variant, char ** std_encoding) {103char *temp = NULL;104char *language = NULL, *country = NULL, *variant = NULL,105*encoding = NULL;106char *p, *encoding_variant, *old_temp, *old_ev;107char *lc;108109/* Query the locale set for the category */110111#ifdef MACOSX112lc = setupMacOSXLocale(cat); // malloc'd memory, need to free113#else114lc = setlocale(cat, NULL);115#endif116117#ifndef __linux__118if (lc == NULL) {119return 0;120}121122temp = malloc(strlen(lc) + 1);123if (temp == NULL) {124#ifdef MACOSX125free(lc); // malloced memory126#endif127JNU_ThrowOutOfMemoryError(env, NULL);128return 0;129}130131if (cat == LC_CTYPE) {132/*133* Workaround for Solaris bug 4201684: Xlib doesn't like @euro134* locales. Since we don't depend on the libc @euro behavior,135* we just remove the qualifier.136* On Linux, the bug doesn't occur; on the other hand, @euro137* is needed there because it's a shortcut that also determines138* the encoding - without it, we wouldn't get ISO-8859-15.139* Therefore, this code section is Solaris-specific.140*/141strcpy(temp, lc);142p = strstr(temp, "@euro");143if (p != NULL) {144*p = '\0';145setlocale(LC_ALL, temp);146}147}148#else149if (lc == NULL || !strcmp(lc, "C") || !strcmp(lc, "POSIX")) {150lc = "en_US";151}152153temp = malloc(strlen(lc) + 1);154if (temp == NULL) {155JNU_ThrowOutOfMemoryError(env, NULL);156return 0;157}158159#endif160161/*162* locale string format in Solaris is163* <language name>_<country name>.<encoding name>@<variant name>164* <country name>, <encoding name>, and <variant name> are optional.165*/166167strcpy(temp, lc);168#ifdef MACOSX169free(lc); // malloced memory170#endif171/* Parse the language, country, encoding, and variant from the172* locale. Any of the elements may be missing, but they must occur173* in the order language_country.encoding@variant, and must be174* preceded by their delimiter (except for language).175*176* If the locale name (without .encoding@variant, if any) matches177* any of the names in the locale_aliases list, map it to the178* corresponding full locale name. Most of the entries in the179* locale_aliases list are locales that include a language name but180* no country name, and this facility is used to map each language181* to a default country if that's possible. It's also used to map182* the Solaris locale aliases to their proper Java locale IDs.183*/184185encoding_variant = malloc(strlen(temp)+1);186if (encoding_variant == NULL) {187free(temp);188JNU_ThrowOutOfMemoryError(env, NULL);189return 0;190}191192if ((p = strchr(temp, '.')) != NULL) {193strcpy(encoding_variant, p); /* Copy the leading '.' */194*p = '\0';195} else if ((p = strchr(temp, '@')) != NULL) {196strcpy(encoding_variant, p); /* Copy the leading '@' */197*p = '\0';198} else {199*encoding_variant = '\0';200}201202if (mapLookup(locale_aliases, temp, &p)) {203old_temp = temp;204temp = realloc(temp, strlen(p)+1);205if (temp == NULL) {206free(old_temp);207free(encoding_variant);208JNU_ThrowOutOfMemoryError(env, NULL);209return 0;210}211strcpy(temp, p);212old_ev = encoding_variant;213encoding_variant = realloc(encoding_variant, strlen(temp)+1);214if (encoding_variant == NULL) {215free(old_ev);216free(temp);217JNU_ThrowOutOfMemoryError(env, NULL);218return 0;219}220// check the "encoding_variant" again, if any.221if ((p = strchr(temp, '.')) != NULL) {222strcpy(encoding_variant, p); /* Copy the leading '.' */223*p = '\0';224} else if ((p = strchr(temp, '@')) != NULL) {225strcpy(encoding_variant, p); /* Copy the leading '@' */226*p = '\0';227}228}229230language = temp;231if ((country = strchr(temp, '_')) != NULL) {232*country++ = '\0';233}234235p = encoding_variant;236if ((encoding = strchr(p, '.')) != NULL) {237p[encoding++ - p] = '\0';238p = encoding;239}240if ((variant = strchr(p, '@')) != NULL) {241p[variant++ - p] = '\0';242}243244/* Normalize the language name */245if (std_language != NULL) {246*std_language = "en";247if (language != NULL && mapLookup(language_names, language, std_language) == 0) {248*std_language = malloc(strlen(language)+1);249strcpy(*std_language, language);250}251}252253/* Normalize the country name */254if (std_country != NULL && country != NULL) {255if (mapLookup(country_names, country, std_country) == 0) {256*std_country = malloc(strlen(country)+1);257strcpy(*std_country, country);258}259}260261/* Normalize the script and variant name. Note that we only use262* variants listed in the mapping array; others are ignored.263*/264if (variant != NULL) {265if (std_script != NULL) {266mapLookup(script_names, variant, std_script);267}268269if (std_variant != NULL) {270mapLookup(variant_names, variant, std_variant);271}272}273274/* Normalize the encoding name. Note that we IGNORE the string275* 'encoding' extracted from the locale name above. Instead, we use the276* more reliable method of calling nl_langinfo(CODESET). This function277* returns an empty string if no encoding is set for the given locale278* (e.g., the C or POSIX locales); we use the default ISO 8859-1279* converter for such locales.280*/281if (std_encoding != NULL) {282/* OK, not so reliable - nl_langinfo() gives wrong answers on283* Euro locales, in particular. */284if (strcmp(p, "ISO8859-15") == 0)285p = "ISO8859-15";286else287p = nl_langinfo(CODESET);288289/* Convert the bare "646" used on Solaris to a proper IANA name */290if (strcmp(p, "646") == 0)291p = "ISO646-US";292293/* return same result nl_langinfo would return for en_UK,294* in order to use optimizations. */295*std_encoding = (*p != '\0') ? p : "ISO8859-1";296297#ifdef __linux__298/*299* Remap the encoding string to a different value for japanese300* locales on linux so that customized converters are used instead301* of the default converter for "EUC-JP". The customized converters302* omit support for the JIS0212 encoding which is not supported by303* the variant of "EUC-JP" encoding used on linux304*/305if (strcmp(p, "EUC-JP") == 0) {306*std_encoding = "EUC-JP-LINUX";307}308#else309if (strcmp(p,"eucJP") == 0) {310/* For Solaris use customized vendor defined character311* customized EUC-JP converter312*/313*std_encoding = "eucJP-open";314} else if (strcmp(p, "Big5") == 0 || strcmp(p, "BIG5") == 0) {315/*316* Remap the encoding string to Big5_Solaris which augments317* the default converter for Solaris Big5 locales to include318* seven additional ideographic characters beyond those included319* in the Java "Big5" converter.320*/321*std_encoding = "Big5_Solaris";322} else if (strcmp(p, "Big5-HKSCS") == 0) {323/*324* Solaris uses HKSCS2001325*/326*std_encoding = "Big5-HKSCS-2001";327}328#endif329#ifdef MACOSX330/*331* For the case on MacOS X where encoding is set to US-ASCII, but we332* don't have any encoding hints from LANG/LC_ALL/LC_CTYPE, use UTF-8333* instead.334*335* The contents of ASCII files will still be read and displayed336* correctly, but so will files containing UTF-8 characters beyond the337* standard ASCII range.338*339* Specifically, this allows apps launched by double-clicking a .jar340* file to correctly read UTF-8 files using the default encoding (see341* 8011194).342*/343if (strcmp(p,"US-ASCII") == 0 && getenv("LANG") == NULL &&344getenv("LC_ALL") == NULL && getenv("LC_CTYPE") == NULL) {345*std_encoding = "UTF-8";346}347#endif348}349350free(temp);351free(encoding_variant);352353return 1;354}355356#ifdef JAVASE_EMBEDDED357/* Determine the default embedded toolkit based on whether libawt_xawt358* exists in the JRE. This can still be overridden by -Dawt.toolkit=XXX359*/360static char* getEmbeddedToolkit() {361Dl_info dlinfo;362char buf[MAXPATHLEN];363int32_t len;364char *p;365struct stat statbuf;366367/* Get address of this library and the directory containing it. */368dladdr((void *)getEmbeddedToolkit, &dlinfo);369realpath((char *)dlinfo.dli_fname, buf);370len = strlen(buf);371p = strrchr(buf, '/');372/* Default AWT Toolkit on Linux and Solaris is XAWT (libawt_xawt.so). */373strncpy(p, "/libawt_xawt.so", MAXPATHLEN-len-1);374/* Check if it exists */375if (stat(buf, &statbuf) == -1 && errno == ENOENT) {376/* No - this is a reduced-headless-jre so use special HToolkit */377return "sun.awt.HToolkit";378}379else {380/* Yes - this is a headful JRE so fallback to SE defaults */381return NULL;382}383}384#endif385386/* This function gets called very early, before VM_CALLS are setup.387* Do not use any of the VM_CALLS entries!!!388*/389java_props_t *390GetJavaProperties(JNIEnv *env)391{392static java_props_t sprops;393char *v; /* tmp var */394395if (sprops.user_dir) {396return &sprops;397}398399/* tmp dir */400sprops.tmp_dir = P_tmpdir;401#ifdef MACOSX402/* darwin has a per-user temp dir */403static char tmp_path[PATH_MAX];404int pathSize = confstr(_CS_DARWIN_USER_TEMP_DIR, tmp_path, PATH_MAX);405if (pathSize > 0 && pathSize <= PATH_MAX) {406sprops.tmp_dir = tmp_path;407}408#endif /* MACOSX */409410/* Printing properties */411#ifdef MACOSX412sprops.printerJob = "sun.lwawt.macosx.CPrinterJob";413#else414sprops.printerJob = "sun.print.PSPrinterJob";415#endif416417/* patches/service packs installed */418sprops.patch_level = "unknown";419420/* Java 2D/AWT properties */421#ifdef MACOSX422// Always the same GraphicsEnvironment and Toolkit on Mac OS X423sprops.graphics_env = "sun.awt.CGraphicsEnvironment";424sprops.awt_toolkit = "sun.lwawt.macosx.LWCToolkit";425426// check if we're in a GUI login session and set java.awt.headless=true if not427sprops.awt_headless = isInAquaSession() ? NULL : "true";428#else429sprops.graphics_env = "sun.awt.X11GraphicsEnvironment";430#ifdef JAVASE_EMBEDDED431sprops.awt_toolkit = getEmbeddedToolkit();432if (sprops.awt_toolkit == NULL) // default as below433#endif434sprops.awt_toolkit = "sun.awt.X11.XToolkit";435#endif436437/* This is used only for debugging of font problems. */438v = getenv("JAVA2D_FONTPATH");439sprops.font_dir = v ? v : NULL;440441#ifdef SI_ISALIST442/* supported instruction sets */443{444char list[258];445sysinfo(SI_ISALIST, list, sizeof(list));446sprops.cpu_isalist = strdup(list);447}448#else449sprops.cpu_isalist = NULL;450#endif451452/* endianness of platform */453{454unsigned int endianTest = 0xff000000;455if (((char*)(&endianTest))[0] != 0)456sprops.cpu_endian = "big";457else458sprops.cpu_endian = "little";459}460461/* os properties */462{463#ifdef MACOSX464setOSNameAndVersion(&sprops);465#else466struct utsname name;467uname(&name);468sprops.os_name = strdup(name.sysname);469#ifdef _AIX470{471char *os_version = malloc(strlen(name.version) +472strlen(name.release) + 2);473if (os_version != NULL) {474strcpy(os_version, name.version);475strcat(os_version, ".");476strcat(os_version, name.release);477}478sprops.os_version = os_version;479}480#else481sprops.os_version = strdup(name.release);482#endif /* _AIX */483#endif /* MACOSX */484485sprops.os_arch = ARCHPROPNAME;486487if (getenv("GNOME_DESKTOP_SESSION_ID") != NULL) {488sprops.desktop = "gnome";489}490else {491sprops.desktop = NULL;492}493}494495/* ABI property (optional) */496#ifdef JDK_ARCH_ABI_PROP_NAME497sprops.sun_arch_abi = JDK_ARCH_ABI_PROP_NAME;498#endif499500/* Determine the language, country, variant, and encoding from the host,501* and store these in the user.language, user.country, user.variant and502* file.encoding system properties. */503setlocale(LC_ALL, "");504if (ParseLocale(env, LC_CTYPE,505&(sprops.format_language),506&(sprops.format_script),507&(sprops.format_country),508&(sprops.format_variant),509&(sprops.encoding))) {510ParseLocale(env, LC_MESSAGES,511&(sprops.language),512&(sprops.script),513&(sprops.country),514&(sprops.variant),515NULL);516} else {517sprops.language = "en";518sprops.encoding = "ISO8859-1";519}520sprops.display_language = sprops.language;521sprops.display_script = sprops.script;522sprops.display_country = sprops.country;523sprops.display_variant = sprops.variant;524525/* ParseLocale failed with OOME */526JNU_CHECK_EXCEPTION_RETURN(env, NULL);527528#ifdef MACOSX529sprops.sun_jnu_encoding = "UTF-8";530#else531sprops.sun_jnu_encoding = sprops.encoding;532#endif533534#ifdef _ALLBSD_SOURCE535#if BYTE_ORDER == _LITTLE_ENDIAN536sprops.unicode_encoding = "UnicodeLittle";537#else538sprops.unicode_encoding = "UnicodeBig";539#endif540#else /* !_ALLBSD_SOURCE */541#ifdef __linux__542#if __BYTE_ORDER == __LITTLE_ENDIAN543sprops.unicode_encoding = "UnicodeLittle";544#else545sprops.unicode_encoding = "UnicodeBig";546#endif547#else548sprops.unicode_encoding = "UnicodeBig";549#endif550#endif /* _ALLBSD_SOURCE */551552/* user properties */553{554struct passwd *pwent = getpwuid(getuid());555sprops.user_name = pwent ? strdup(pwent->pw_name) : "?";556#ifdef MACOSX557setUserHome(&sprops);558#else559sprops.user_home = pwent ? strdup(pwent->pw_dir) : NULL;560#endif561if (sprops.user_home == NULL) {562sprops.user_home = "?";563}564}565566/* User TIMEZONE */567{568/*569* We defer setting up timezone until it's actually necessary.570* Refer to TimeZone.getDefault(). However, the system571* property is necessary to be able to be set by the command572* line interface -D. Here temporarily set a null string to573* timezone.574*/575tzset(); /* for compatibility */576sprops.timezone = "";577}578579/* Current directory */580{581char buf[MAXPATHLEN];582errno = 0;583if (getcwd(buf, sizeof(buf)) == NULL)584JNU_ThrowByName(env, "java/lang/Error",585"Properties init: Could not determine current working directory.");586else587sprops.user_dir = strdup(buf);588}589590sprops.file_separator = "/";591sprops.path_separator = ":";592sprops.line_separator = "\n";593594#ifdef MACOSX595setProxyProperties(&sprops);596#endif597598return &sprops;599}600601jstring602GetStringPlatform(JNIEnv *env, nchar* cstr)603{604return JNU_NewStringPlatform(env, cstr);605}606607608