• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright (c) 1994, 2010, Oracle and/or its affiliates. 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.  Oracle designates this
8   * particular file as subject to the "Classpath" exception as provided
9   * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  #define LOG_TAG "libcore"
26  
27  #include <stdlib.h>
28  #include <string.h>
29  #include <time.h>
30  
31  #include <log/log.h>
32  
33  #include "io_util.h"
34  #include "jni.h"
35  #include "jni_util.h"
36  #include "jvm.h"
37  
38  #include "openssl/opensslv.h"
39  #include "zlib.h"
40  #include <nativehelper/JNIHelp.h>
41  #include <nativehelper/jni_macros.h>
42  
43  #if defined(__ANDROID__)
44  void android_get_LD_LIBRARY_PATH(char*, size_t);
45  #endif
46  
47  #define PUTPROP(props, key, val) \
48      if (1) { \
49          jstring jkey = (*env)->NewStringUTF(env, key); \
50          jstring jval = (*env)->NewStringUTF(env, val); \
51          jobject r = (*env)->CallObjectMethod(env, props, putID, jkey, jval); \
52          if ((*env)->ExceptionOccurred(env)) return NULL; \
53          (*env)->DeleteLocalRef(env, jkey); \
54          (*env)->DeleteLocalRef(env, jval); \
55          (*env)->DeleteLocalRef(env, r); \
56      } else ((void) 0)
57  
58  /*  "key" is a char type string with only ASCII character in it.
59      "val" is a nchar (typedefed in java_props.h) type string  */
60  
61  #define PUTPROP_ForPlatformNString(props, key, val) \
62      if (1) { \
63          jstring jkey = (*env)->NewStringUTF(env, key);  \
64          jstring jval = GetStringPlatform(env, val); \
65          jobject r = (*env)->CallObjectMethod(env, props, putID, jkey, jval); \
66          if ((*env)->ExceptionOccurred(env)) return NULL; \
67          (*env)->DeleteLocalRef(env, jkey); \
68          (*env)->DeleteLocalRef(env, jval); \
69          (*env)->DeleteLocalRef(env, r); \
70      } else ((void) 0)
71  #define REMOVEPROP(props, key) \
72      if (1) { \
73          jstring jkey = JNU_NewStringPlatform(env, key); \
74          jobject r = (*env)->CallObjectMethod(env, props, removeID, jkey); \
75          if ((*env)->ExceptionOccurred(env)) return NULL; \
76          (*env)->DeleteLocalRef(env, jkey); \
77          (*env)->DeleteLocalRef(env, r); \
78      } else ((void) 0)
79  #define GETPROP(props, key, jret) \
80      if (1) { \
81          jstring jkey = JNU_NewStringPlatform(env, key); \
82          (jret) = (*env)->CallObjectMethod(env, props, getPropID, jkey); \
83          if ((*env)->ExceptionOccurred(env)) return NULL; \
84          (*env)->DeleteLocalRef(env, jkey); \
85      } else ((void) 0)
86  
87  #ifndef VENDOR /* Third party may overwrite this. */
88  #define VENDOR "Oracle Corporation"
89  #define VENDOR_URL "http://java.oracle.com/"
90  #define VENDOR_URL_BUG "http://bugreport.sun.com/bugreport/"
91  #endif
92  
93  #define JAVA_MAX_SUPPORTED_VERSION 51
94  #define JAVA_MAX_SUPPORTED_MINOR_VERSION 0
95  
96  #ifdef JAVA_SPECIFICATION_VENDOR /* Third party may NOT overwrite this. */
97    #error "ERROR: No override of JAVA_SPECIFICATION_VENDOR is allowed"
98  #else
99    #define JAVA_SPECIFICATION_VENDOR "Oracle Corporation"
100  #endif
101  
102  /*
103   * The following three functions implement setter methods for
104   * java.lang.System.{in, out, err}. They are natively implemented
105   * because they violate the semantics of the language (i.e. set final
106   * variable).
107   */
108  JNIEXPORT void JNICALL
System_setIn0(JNIEnv * env,jclass cla,jobject stream)109  System_setIn0(JNIEnv *env, jclass cla, jobject stream)
110  {
111      jfieldID fid =
112          (*env)->GetStaticFieldID(env,cla,"in","Ljava/io/InputStream;");
113      if (fid == 0)
114          return;
115      (*env)->SetStaticObjectField(env,cla,fid,stream);
116  }
117  
118  JNIEXPORT void JNICALL
System_setOut0(JNIEnv * env,jclass cla,jobject stream)119  System_setOut0(JNIEnv *env, jclass cla, jobject stream)
120  {
121      jfieldID fid =
122          (*env)->GetStaticFieldID(env,cla,"out","Ljava/io/PrintStream;");
123      if (fid == 0)
124          return;
125      (*env)->SetStaticObjectField(env,cla,fid,stream);
126  }
127  
128  JNIEXPORT void JNICALL
System_setErr0(JNIEnv * env,jclass cla,jobject stream)129  System_setErr0(JNIEnv *env, jclass cla, jobject stream)
130  {
131      jfieldID fid =
132          (*env)->GetStaticFieldID(env,cla,"err","Ljava/io/PrintStream;");
133      if (fid == 0)
134          return;
135      (*env)->SetStaticObjectField(env,cla,fid,stream);
136  }
137  
cpchars(jchar * dst,char * src,int n)138  static void cpchars(jchar *dst, char *src, int n)
139  {
140      int i;
141      for (i = 0; i < n; i++) {
142          dst[i] = src[i];
143      }
144  }
145  
146  JNIEXPORT jstring JNICALL
System_mapLibraryName(JNIEnv * env,jclass ign,jstring libname)147  System_mapLibraryName(JNIEnv *env, jclass ign, jstring libname)
148  {
149      int len;
150      int prefix_len = (int) strlen(JNI_LIB_PREFIX);
151      int suffix_len = (int) strlen(JNI_LIB_SUFFIX);
152  
153      jchar chars[256];
154      if (libname == NULL) {
155          JNU_ThrowNullPointerException(env, 0);
156          return NULL;
157      }
158      len = (*env)->GetStringLength(env, libname);
159      if (len > 240) {
160          JNU_ThrowIllegalArgumentException(env, "name too long");
161          return NULL;
162      }
163      cpchars(chars, JNI_LIB_PREFIX, prefix_len);
164      (*env)->GetStringRegion(env, libname, 0, len, chars + prefix_len);
165      len += prefix_len;
166      cpchars(chars + len, JNI_LIB_SUFFIX, suffix_len);
167      len += suffix_len;
168  
169      return (*env)->NewString(env, chars, len);
170  }
171  
System_specialProperties(JNIEnv * env,jclass ignored)172  static jobjectArray System_specialProperties(JNIEnv* env, jclass ignored) {
173      jclass stringClass = (*env)->FindClass(env, "java/lang/String");
174      jobjectArray result = (*env)->NewObjectArray(env, 4, stringClass, NULL);
175  
176      char path[PATH_MAX];
177      char* process_path = getcwd(path, sizeof(path));
178      char user_dir[PATH_MAX + 10] = "user.dir=";
179      strncat(user_dir, process_path, PATH_MAX);
180      jstring user_dir_str = (*env)->NewStringUTF(env, user_dir);
181      if ((*env)->ExceptionCheck(env)) {
182          return NULL;
183      }
184      (*env)->SetObjectArrayElement(env, result, 0, user_dir_str);
185      if ((*env)->ExceptionCheck(env)) {
186          return NULL;
187      }
188      jstring zlib_str = (*env)->NewStringUTF(env, "android.zlib.version=" ZLIB_VERSION);
189      if ((*env)->ExceptionCheck(env)) {
190          return NULL;
191      }
192      (*env)->SetObjectArrayElement(env, result, 1, zlib_str);
193      if ((*env)->ExceptionCheck(env)) {
194          return NULL;
195      }
196      jstring ssl_str = (*env)->NewStringUTF(env, "android.openssl.version=" OPENSSL_VERSION_TEXT);
197      if ((*env)->ExceptionCheck(env)) {
198          return NULL;
199      }
200      (*env)->SetObjectArrayElement(env, result, 2, ssl_str);
201      if ((*env)->ExceptionCheck(env)) {
202          return NULL;
203      }
204  
205  
206      const char* library_path = getenv("LD_LIBRARY_PATH");
207  #if defined(__ANDROID__)
208      if (library_path == NULL) {
209          android_get_LD_LIBRARY_PATH(path, sizeof(path));
210          library_path = path;
211      }
212  #endif
213      if (library_path == NULL) {
214          library_path = "";
215      }
216      char* java_path = malloc(strlen("java.library.path=") + strlen(library_path) + 1);
217      strcpy(java_path, "java.library.path=");
218      strcat(java_path, library_path);
219      jstring java_path_str = (*env)->NewStringUTF(env, java_path);
220      free((void*)java_path);
221      if ((*env)->ExceptionCheck(env)) {
222          return NULL;
223      }
224      (*env)->SetObjectArrayElement(env, result, 3, java_path_str);
225      if ((*env)->ExceptionCheck(env)) {
226          return NULL;
227      }
228  
229      return result;
230  }
231  
System_log(JNIEnv * env,jclass ignored,jchar type,jstring javaMessage,jthrowable exception)232  static void System_log(JNIEnv* env, jclass ignored, jchar type, jstring javaMessage, jthrowable exception) {
233      int priority;
234      switch (type) {
235      case 'D': case 'd': priority = ANDROID_LOG_DEBUG;   break;
236      case 'E': case 'e': priority = ANDROID_LOG_ERROR;   break;
237      case 'F': case 'f': priority = ANDROID_LOG_FATAL;   break;
238      case 'I': case 'i': priority = ANDROID_LOG_INFO;    break;
239      case 'S': case 's': priority = ANDROID_LOG_SILENT;  break;
240      case 'V': case 'v': priority = ANDROID_LOG_VERBOSE; break;
241      case 'W': case 'w': priority = ANDROID_LOG_WARN;    break;
242      default:            priority = ANDROID_LOG_DEFAULT; break;
243      }
244  
245      WITH_PLATFORM_STRING(env, javaMessage, message) {
246        LOG_PRI(priority, "System", "%s", message);
247      } END_PLATFORM_STRING(env, message);
248  
249      if (exception != NULL) {
250          jniLogException(env, priority, "System", exception);
251      }
252  }
253  
System_nanoTime()254  static jlong System_nanoTime() {
255    struct timespec now;
256    clock_gettime(CLOCK_MONOTONIC, &now);
257    return now.tv_sec * 1000000000LL + now.tv_nsec;
258  }
259  
System_currentTimeMillis()260  static jlong System_currentTimeMillis() {
261    return JVM_CurrentTimeMillis(NULL, NULL);
262  }
263  
264  static JNINativeMethod gMethods[] = {
265    NATIVE_METHOD(System, mapLibraryName, "(Ljava/lang/String;)Ljava/lang/String;"),
266    NATIVE_METHOD(System, setErr0, "(Ljava/io/PrintStream;)V"),
267    NATIVE_METHOD(System, setOut0, "(Ljava/io/PrintStream;)V"),
268    NATIVE_METHOD(System, setIn0, "(Ljava/io/InputStream;)V"),
269    NATIVE_METHOD(System, specialProperties, "()[Ljava/lang/String;"),
270    NATIVE_METHOD(System, log, "(CLjava/lang/String;Ljava/lang/Throwable;)V"),
271    CRITICAL_NATIVE_METHOD(System, currentTimeMillis, "()J"),
272    CRITICAL_NATIVE_METHOD(System, nanoTime, "()J"),
273  };
274  
register_java_lang_System(JNIEnv * env)275  void register_java_lang_System(JNIEnv* env) {
276    jniRegisterNativeMethods(env, "java/lang/System", gMethods, NELEM(gMethods));
277  }
278