Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/native/java/lang/System.c
38829 views
/*1* Copyright (c) 1994, 2019, 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#include <string.h>2627#include "jni.h"28#include "jni_util.h"29#include "jvm.h"30#include "java_props.h"3132#include "java_lang_System.h"3334#define OBJ "Ljava/lang/Object;"3536/* Only register the performance-critical methods */37static JNINativeMethod methods[] = {38{"currentTimeMillis", "()J", (void *)&JVM_CurrentTimeMillis},39{"nanoTime", "()J", (void *)&JVM_NanoTime},40{"arraycopy", "(" OBJ "I" OBJ "II)V", (void *)&JVM_ArrayCopy},41};4243#undef OBJ4445JNIEXPORT void JNICALL46Java_java_lang_System_registerNatives(JNIEnv *env, jclass cls)47{48(*env)->RegisterNatives(env, cls,49methods, sizeof(methods)/sizeof(methods[0]));50}5152JNIEXPORT jint JNICALL53Java_java_lang_System_identityHashCode(JNIEnv *env, jobject this, jobject x)54{55return JVM_IHashCode(env, x);56}5758#define PUTPROP(props, key, val) \59if (1) { \60jstring jkey, jval; \61jobject r; \62jkey = (*env)->NewStringUTF(env, key); \63if (jkey == NULL) return NULL; \64jval = (*env)->NewStringUTF(env, val); \65if (jval == NULL) return NULL; \66r = (*env)->CallObjectMethod(env, props, putID, jkey, jval); \67if ((*env)->ExceptionOccurred(env)) return NULL; \68(*env)->DeleteLocalRef(env, jkey); \69(*env)->DeleteLocalRef(env, jval); \70(*env)->DeleteLocalRef(env, r); \71} else ((void) 0)7273/* "key" is a char type string with only ASCII character in it.74"val" is a nchar (typedefed in java_props.h) type string */7576#define PUTPROP_ForPlatformNString(props, key, val) \77if (1) { \78jstring jkey, jval; \79jobject r; \80jkey = (*env)->NewStringUTF(env, key); \81if (jkey == NULL) return NULL; \82jval = GetStringPlatform(env, val); \83if (jval == NULL) return NULL; \84r = (*env)->CallObjectMethod(env, props, putID, jkey, jval); \85if ((*env)->ExceptionOccurred(env)) return NULL; \86(*env)->DeleteLocalRef(env, jkey); \87(*env)->DeleteLocalRef(env, jval); \88(*env)->DeleteLocalRef(env, r); \89} else ((void) 0)90#define REMOVEPROP(props, key) \91if (1) { \92jstring jkey; \93jobject r; \94jkey = JNU_NewStringPlatform(env, key); \95if (jkey == NULL) return NULL; \96r = (*env)->CallObjectMethod(env, props, removeID, jkey); \97if ((*env)->ExceptionOccurred(env)) return NULL; \98(*env)->DeleteLocalRef(env, jkey); \99(*env)->DeleteLocalRef(env, r); \100} else ((void) 0)101#define GETPROP(props, key, jret) \102if (1) { \103jstring jkey = JNU_NewStringPlatform(env, key); \104if (jkey == NULL) return NULL; \105jret = (*env)->CallObjectMethod(env, props, getPropID, jkey); \106if ((*env)->ExceptionOccurred(env)) return NULL; \107(*env)->DeleteLocalRef(env, jkey); \108} else ((void) 0)109110/* Third party may overwrite these values. */111#ifndef VENDOR112#define VENDOR "Oracle Corporation"113#endif114#ifndef VENDOR_URL115#define VENDOR_URL "http://java.oracle.com/"116#endif117#ifndef VENDOR_URL_BUG118#define VENDOR_URL_BUG "http://bugreport.sun.com/bugreport/"119#endif120121#define JAVA_MAX_SUPPORTED_VERSION 52122#define JAVA_MAX_SUPPORTED_MINOR_VERSION 0123124#ifdef JAVA_SPECIFICATION_VENDOR /* Third party may NOT overwrite this. */125#error "ERROR: No override of JAVA_SPECIFICATION_VENDOR is allowed"126#else127#define JAVA_SPECIFICATION_VENDOR "Oracle Corporation"128#endif129130static int fmtdefault; // boolean value131jobject fillI18nProps(JNIEnv *env, jobject props, char *baseKey,132char *platformDispVal, char *platformFmtVal,133jmethodID putID, jmethodID getPropID) {134jstring jVMBaseVal = NULL;135136GETPROP(props, baseKey, jVMBaseVal);137if (jVMBaseVal) {138// user specified the base property. there's nothing to do here.139(*env)->DeleteLocalRef(env, jVMBaseVal);140} else {141char buf[64];142jstring jVMVal = NULL;143const char *baseVal = "";144145/* user.xxx base property */146if (fmtdefault) {147if (platformFmtVal) {148PUTPROP(props, baseKey, platformFmtVal);149baseVal = platformFmtVal;150}151} else {152if (platformDispVal) {153PUTPROP(props, baseKey, platformDispVal);154baseVal = platformDispVal;155}156}157158/* user.xxx.display property */159jio_snprintf(buf, sizeof(buf), "%s.display", baseKey);160GETPROP(props, buf, jVMVal);161if (jVMVal == NULL) {162if (platformDispVal && (strcmp(baseVal, platformDispVal) != 0)) {163PUTPROP(props, buf, platformDispVal);164}165} else {166(*env)->DeleteLocalRef(env, jVMVal);167}168169/* user.xxx.format property */170jio_snprintf(buf, sizeof(buf), "%s.format", baseKey);171GETPROP(props, buf, jVMVal);172if (jVMVal == NULL) {173if (platformFmtVal && (strcmp(baseVal, platformFmtVal) != 0)) {174PUTPROP(props, buf, platformFmtVal);175}176} else {177(*env)->DeleteLocalRef(env, jVMVal);178}179}180181return NULL;182}183184JNIEXPORT jobject JNICALL185Java_java_lang_System_initProperties(JNIEnv *env, jclass cla, jobject props)186{187char buf[128];188java_props_t *sprops;189jmethodID putID, removeID, getPropID;190jobject ret = NULL;191jstring jVMVal = NULL;192193sprops = GetJavaProperties(env);194CHECK_NULL_RETURN(sprops, NULL);195196putID = (*env)->GetMethodID(env,197(*env)->GetObjectClass(env, props),198"put",199"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");200CHECK_NULL_RETURN(putID, NULL);201202removeID = (*env)->GetMethodID(env,203(*env)->GetObjectClass(env, props),204"remove",205"(Ljava/lang/Object;)Ljava/lang/Object;");206CHECK_NULL_RETURN(removeID, NULL);207208getPropID = (*env)->GetMethodID(env,209(*env)->GetObjectClass(env, props),210"getProperty",211"(Ljava/lang/String;)Ljava/lang/String;");212CHECK_NULL_RETURN(getPropID, NULL);213214PUTPROP(props, "java.specification.version",215JDK_MAJOR_VERSION "." JDK_MINOR_VERSION);216PUTPROP(props, "java.specification.name",217"Java Platform API Specification");218PUTPROP(props, "java.specification.vendor",219JAVA_SPECIFICATION_VENDOR);220221PUTPROP(props, "java.version", RELEASE);222PUTPROP(props, "java.vendor", VENDOR);223PUTPROP(props, "java.vendor.url", VENDOR_URL);224PUTPROP(props, "java.vendor.url.bug", VENDOR_URL_BUG);225226jio_snprintf(buf, sizeof(buf), "%d.%d", JAVA_MAX_SUPPORTED_VERSION,227JAVA_MAX_SUPPORTED_MINOR_VERSION);228PUTPROP(props, "java.class.version", buf);229230if (sprops->awt_toolkit) {231PUTPROP(props, "awt.toolkit", sprops->awt_toolkit);232}233#ifdef MACOSX234if (sprops->awt_headless) {235PUTPROP(props, "java.awt.headless", sprops->awt_headless);236}237#endif238239/* os properties */240PUTPROP(props, "os.name", sprops->os_name);241PUTPROP(props, "os.version", sprops->os_version);242PUTPROP(props, "os.arch", sprops->os_arch);243244#ifdef JDK_ARCH_ABI_PROP_NAME245PUTPROP(props, "sun.arch.abi", sprops->sun_arch_abi);246#endif247248/* file system properties */249PUTPROP(props, "file.separator", sprops->file_separator);250PUTPROP(props, "path.separator", sprops->path_separator);251PUTPROP(props, "line.separator", sprops->line_separator);252253/*254* user.language255* user.script, user.country, user.variant (if user's environment specifies them)256* file.encoding257* file.encoding.pkg258*/259PUTPROP(props, "user.language", sprops->language);260if (sprops->script) {261PUTPROP(props, "user.script", sprops->script);262}263if (sprops->country) {264PUTPROP(props, "user.country", sprops->country);265}266if (sprops->variant) {267PUTPROP(props, "user.variant", sprops->variant);268}269PUTPROP(props, "file.encoding", sprops->encoding);270PUTPROP(props, "sun.jnu.encoding", sprops->sun_jnu_encoding);271if (sprops->sun_stdout_encoding != NULL) {272PUTPROP(props, "sun.stdout.encoding", sprops->sun_stdout_encoding);273}274if (sprops->sun_stderr_encoding != NULL) {275PUTPROP(props, "sun.stderr.encoding", sprops->sun_stderr_encoding);276}277PUTPROP(props, "file.encoding.pkg", "sun.io");278279/* unicode_encoding specifies the default endianness */280PUTPROP(props, "sun.io.unicode.encoding", sprops->unicode_encoding);281PUTPROP(props, "sun.cpu.isalist",282(sprops->cpu_isalist ? sprops->cpu_isalist : ""));283PUTPROP(props, "sun.cpu.endian", sprops->cpu_endian);284285286#ifdef MACOSX287/* Proxy setting properties */288if (sprops->httpProxyEnabled) {289PUTPROP(props, "http.proxyHost", sprops->httpHost);290PUTPROP(props, "http.proxyPort", sprops->httpPort);291}292293if (sprops->httpsProxyEnabled) {294PUTPROP(props, "https.proxyHost", sprops->httpsHost);295PUTPROP(props, "https.proxyPort", sprops->httpsPort);296}297298if (sprops->ftpProxyEnabled) {299PUTPROP(props, "ftp.proxyHost", sprops->ftpHost);300PUTPROP(props, "ftp.proxyPort", sprops->ftpPort);301}302303if (sprops->socksProxyEnabled) {304PUTPROP(props, "socksProxyHost", sprops->socksHost);305PUTPROP(props, "socksProxyPort", sprops->socksPort);306}307308if (sprops->gopherProxyEnabled) {309// The gopher client is different in that it expects an 'is this set?' flag that the others don't.310PUTPROP(props, "gopherProxySet", "true");311PUTPROP(props, "gopherProxyHost", sprops->gopherHost);312PUTPROP(props, "gopherProxyPort", sprops->gopherPort);313} else {314PUTPROP(props, "gopherProxySet", "false");315}316317// Mac OS X only has a single proxy exception list which applies318// to all protocols319if (sprops->exceptionList) {320PUTPROP(props, "http.nonProxyHosts", sprops->exceptionList);321// HTTPS: implementation in jsse.jar uses http.nonProxyHosts322PUTPROP(props, "ftp.nonProxyHosts", sprops->exceptionList);323PUTPROP(props, "socksNonProxyHosts", sprops->exceptionList);324}325#endif326327/* !!! DO NOT call PUTPROP_ForPlatformNString before this line !!!328* !!! I18n properties have not been set up yet !!!329*/330331/* Printing properties */332/* Note: java.awt.printerjob is an implementation private property which333* just happens to have a java.* name because it is referenced in334* a java.awt class. It is the mechanism by which the implementation335* finds the appropriate class in the JRE for the platform.336* It is explicitly not designed to be overridden by clients as337* a way of replacing the implementation class, and in any case338* the mechanism by which the class is loaded is constrained to only339* find and load classes that are part of the JRE.340* This property may be removed if that mechanism is redesigned341*/342PUTPROP(props, "java.awt.printerjob", sprops->printerJob);343344/* data model */345if (sizeof(sprops) == 4) {346sprops->data_model = "32";347} else if (sizeof(sprops) == 8) {348sprops->data_model = "64";349} else {350sprops->data_model = "unknown";351}352PUTPROP(props, "sun.arch.data.model", \353sprops->data_model);354355/* patch level */356PUTPROP(props, "sun.os.patch.level", \357sprops->patch_level);358359/* Java2D properties */360/* Note: java.awt.graphicsenv is an implementation private property which361* just happens to have a java.* name because it is referenced in362* a java.awt class. It is the mechanism by which the implementation363* finds the appropriate class in the JRE for the platform.364* It is explicitly not designed to be overridden by clients as365* a way of replacing the implementation class, and in any case366* the mechanism by which the class is loaded is constrained to only367* find and load classes that are part of the JRE.368* This property may be removed if that mechanism is redesigned369*/370PUTPROP(props, "java.awt.graphicsenv", sprops->graphics_env);371if (sprops->font_dir != NULL) {372PUTPROP_ForPlatformNString(props,373"sun.java2d.fontpath", sprops->font_dir);374}375376PUTPROP_ForPlatformNString(props, "java.io.tmpdir", sprops->tmp_dir);377378PUTPROP_ForPlatformNString(props, "user.name", sprops->user_name);379PUTPROP_ForPlatformNString(props, "user.home", sprops->user_home);380381PUTPROP(props, "user.timezone", sprops->timezone);382383PUTPROP_ForPlatformNString(props, "user.dir", sprops->user_dir);384385/* This is a sun. property as it is currently only set for Gnome and386* Windows desktops.387*/388if (sprops->desktop != NULL) {389PUTPROP(props, "sun.desktop", sprops->desktop);390}391392/*393* unset "user.language", "user.script", "user.country", and "user.variant"394* in order to tell whether the command line option "-DXXXX=YYYY" is395* specified or not. They will be reset in fillI18nProps() below.396*/397REMOVEPROP(props, "user.language");398REMOVEPROP(props, "user.script");399REMOVEPROP(props, "user.country");400REMOVEPROP(props, "user.variant");401REMOVEPROP(props, "file.encoding");402403ret = JVM_InitProperties(env, props);404405/* Check the compatibility flag */406GETPROP(props, "sun.locale.formatasdefault", jVMVal);407if (jVMVal) {408const char * val = (*env)->GetStringUTFChars(env, jVMVal, 0);409CHECK_NULL_RETURN(val, NULL);410fmtdefault = !strcmp(val, "true");411(*env)->ReleaseStringUTFChars(env, jVMVal, val);412(*env)->DeleteLocalRef(env, jVMVal);413}414415/* reconstruct i18n related properties */416fillI18nProps(env, props, "user.language", sprops->display_language,417sprops->format_language, putID, getPropID);418fillI18nProps(env, props, "user.script",419sprops->display_script, sprops->format_script, putID, getPropID);420fillI18nProps(env, props, "user.country",421sprops->display_country, sprops->format_country, putID, getPropID);422fillI18nProps(env, props, "user.variant",423sprops->display_variant, sprops->format_variant, putID, getPropID);424GETPROP(props, "file.encoding", jVMVal);425if (jVMVal == NULL) {426#ifdef MACOSX427/*428* Since sun_jnu_encoding is now hard-coded to UTF-8 on Mac, we don't429* want to use it to overwrite file.encoding430*/431PUTPROP(props, "file.encoding", sprops->encoding);432#else433if (fmtdefault) {434PUTPROP(props, "file.encoding", sprops->encoding);435} else {436PUTPROP(props, "file.encoding", sprops->sun_jnu_encoding);437}438#endif439} else {440(*env)->DeleteLocalRef(env, jVMVal);441}442443return ret;444}445446/*447* The following three functions implement setter methods for448* java.lang.System.{in, out, err}. They are natively implemented449* because they violate the semantics of the language (i.e. set final450* variable).451*/452JNIEXPORT void JNICALL453Java_java_lang_System_setIn0(JNIEnv *env, jclass cla, jobject stream)454{455jfieldID fid =456(*env)->GetStaticFieldID(env,cla,"in","Ljava/io/InputStream;");457if (fid == 0)458return;459(*env)->SetStaticObjectField(env,cla,fid,stream);460}461462JNIEXPORT void JNICALL463Java_java_lang_System_setOut0(JNIEnv *env, jclass cla, jobject stream)464{465jfieldID fid =466(*env)->GetStaticFieldID(env,cla,"out","Ljava/io/PrintStream;");467if (fid == 0)468return;469(*env)->SetStaticObjectField(env,cla,fid,stream);470}471472JNIEXPORT void JNICALL473Java_java_lang_System_setErr0(JNIEnv *env, jclass cla, jobject stream)474{475jfieldID fid =476(*env)->GetStaticFieldID(env,cla,"err","Ljava/io/PrintStream;");477if (fid == 0)478return;479(*env)->SetStaticObjectField(env,cla,fid,stream);480}481482static void cpchars(jchar *dst, char *src, int n)483{484int i;485for (i = 0; i < n; i++) {486dst[i] = src[i];487}488}489490JNIEXPORT jstring JNICALL491Java_java_lang_System_mapLibraryName(JNIEnv *env, jclass ign, jstring libname)492{493int len;494int prefix_len = (int) strlen(JNI_LIB_PREFIX);495int suffix_len = (int) strlen(JNI_LIB_SUFFIX);496497jchar chars[256];498if (libname == NULL) {499JNU_ThrowNullPointerException(env, 0);500return NULL;501}502len = (*env)->GetStringLength(env, libname);503if (len > 240) {504JNU_ThrowIllegalArgumentException(env, "name too long");505return NULL;506}507cpchars(chars, JNI_LIB_PREFIX, prefix_len);508(*env)->GetStringRegion(env, libname, 0, len, chars + prefix_len);509len += prefix_len;510cpchars(chars + len, JNI_LIB_SUFFIX, suffix_len);511len += suffix_len;512513return (*env)->NewString(env, chars, len);514}515516517