151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it
651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as
751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation.  Oracle designates this
851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided
951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code.
1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT
1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that
1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code).
1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version
1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation,
1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any
2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions.
2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include <string.h>
26de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski#include <stdlib.h>
2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include "jni.h"
2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include "jni_util.h"
3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include "jvm.h"
313f64b8777d7358c99dd201bd01a9444786cb91b0Narayan Kamath#include "io_util.h"
3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
34de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski#include "openssl/opensslv.h"
35de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski#include "zlib.h"
36de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski#include "JNIHelp.h"
37de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski#include "cutils/log.h"
3870b617fe562806bc3e15452a2792fec4355bd54fPrzemyslaw Szczepaniak#if defined(__ANDROID__)
39de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebskivoid android_get_LD_LIBRARY_PATH(char*, size_t);
40de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski#endif
41de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski
42de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski#define NATIVE_METHOD(className, functionName, signature) \
43de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski{ #functionName, signature, (void*)(className ## _ ## functionName) }
4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#define PUTPROP(props, key, val) \
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    if (1) { \
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        jstring jkey = (*env)->NewStringUTF(env, key); \
4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        jstring jval = (*env)->NewStringUTF(env, val); \
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        jobject r = (*env)->CallObjectMethod(env, props, putID, jkey, jval); \
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ((*env)->ExceptionOccurred(env)) return NULL; \
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        (*env)->DeleteLocalRef(env, jkey); \
5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        (*env)->DeleteLocalRef(env, jval); \
5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        (*env)->DeleteLocalRef(env, r); \
5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    } else ((void) 0)
5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*  "key" is a char type string with only ASCII character in it.
5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    "val" is a nchar (typedefed in java_props.h) type string  */
5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#define PUTPROP_ForPlatformNString(props, key, val) \
6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    if (1) { \
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        jstring jkey = (*env)->NewStringUTF(env, key);  \
6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        jstring jval = GetStringPlatform(env, val); \
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        jobject r = (*env)->CallObjectMethod(env, props, putID, jkey, jval); \
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ((*env)->ExceptionOccurred(env)) return NULL; \
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        (*env)->DeleteLocalRef(env, jkey); \
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        (*env)->DeleteLocalRef(env, jval); \
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        (*env)->DeleteLocalRef(env, r); \
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    } else ((void) 0)
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#define REMOVEPROP(props, key) \
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    if (1) { \
7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        jstring jkey = JNU_NewStringPlatform(env, key); \
7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        jobject r = (*env)->CallObjectMethod(env, props, removeID, jkey); \
7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ((*env)->ExceptionOccurred(env)) return NULL; \
7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        (*env)->DeleteLocalRef(env, jkey); \
7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        (*env)->DeleteLocalRef(env, r); \
7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    } else ((void) 0)
7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#define GETPROP(props, key, jret) \
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    if (1) { \
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        jstring jkey = JNU_NewStringPlatform(env, key); \
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        jret = (*env)->CallObjectMethod(env, props, getPropID, jkey); \
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ((*env)->ExceptionOccurred(env)) return NULL; \
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        (*env)->DeleteLocalRef(env, jkey); \
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    } else ((void) 0)
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifndef VENDOR /* Third party may overwrite this. */
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#define VENDOR "Oracle Corporation"
8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#define VENDOR_URL "http://java.oracle.com/"
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#define VENDOR_URL_BUG "http://bugreport.sun.com/bugreport/"
8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif
9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#define JAVA_MAX_SUPPORTED_VERSION 51
9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#define JAVA_MAX_SUPPORTED_MINOR_VERSION 0
9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef JAVA_SPECIFICATION_VENDOR /* Third party may NOT overwrite this. */
9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski  #error "ERROR: No override of JAVA_SPECIFICATION_VENDOR is allowed"
9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#else
9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski  #define JAVA_SPECIFICATION_VENDOR "Oracle Corporation"
9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif
9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The following three functions implement setter methods for
10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * java.lang.System.{in, out, err}. They are natively implemented
10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * because they violate the semantics of the language (i.e. set final
10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * variable).
10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskiJNIEXPORT void JNICALL
107de626ec8a109ea18283d96c720cc57e2f32f67faPiotr JastrzebskiSystem_setIn0(JNIEnv *env, jclass cla, jobject stream)
10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{
10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    jfieldID fid =
11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        (*env)->GetStaticFieldID(env,cla,"in","Ljava/io/InputStream;");
11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    if (fid == 0)
11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return;
11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    (*env)->SetStaticObjectField(env,cla,fid,stream);
11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskiJNIEXPORT void JNICALL
117de626ec8a109ea18283d96c720cc57e2f32f67faPiotr JastrzebskiSystem_setOut0(JNIEnv *env, jclass cla, jobject stream)
11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{
11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    jfieldID fid =
12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        (*env)->GetStaticFieldID(env,cla,"out","Ljava/io/PrintStream;");
12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    if (fid == 0)
12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return;
12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    (*env)->SetStaticObjectField(env,cla,fid,stream);
12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskiJNIEXPORT void JNICALL
127de626ec8a109ea18283d96c720cc57e2f32f67faPiotr JastrzebskiSystem_setErr0(JNIEnv *env, jclass cla, jobject stream)
12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{
12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    jfieldID fid =
13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        (*env)->GetStaticFieldID(env,cla,"err","Ljava/io/PrintStream;");
13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    if (fid == 0)
13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return;
13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    (*env)->SetStaticObjectField(env,cla,fid,stream);
13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskistatic void cpchars(jchar *dst, char *src, int n)
13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{
13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    int i;
13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    for (i = 0; i < n; i++) {
14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        dst[i] = src[i];
14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskiJNIEXPORT jstring JNICALL
145de626ec8a109ea18283d96c720cc57e2f32f67faPiotr JastrzebskiSystem_mapLibraryName(JNIEnv *env, jclass ign, jstring libname)
14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{
14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    int len;
14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    int prefix_len = (int) strlen(JNI_LIB_PREFIX);
14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    int suffix_len = (int) strlen(JNI_LIB_SUFFIX);
15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    jchar chars[256];
15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    if (libname == NULL) {
15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        JNU_ThrowNullPointerException(env, 0);
15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return NULL;
15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    len = (*env)->GetStringLength(env, libname);
15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    if (len > 240) {
15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        JNU_ThrowIllegalArgumentException(env, "name too long");
15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return NULL;
16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    cpchars(chars, JNI_LIB_PREFIX, prefix_len);
16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    (*env)->GetStringRegion(env, libname, 0, len, chars + prefix_len);
16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    len += prefix_len;
16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    cpchars(chars + len, JNI_LIB_SUFFIX, suffix_len);
16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    len += suffix_len;
16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    return (*env)->NewString(env, chars, len);
16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
169de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski
170de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebskistatic jobjectArray System_specialProperties(JNIEnv* env, jclass ignored) {
171de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    jclass stringClass = (*env)->FindClass(env, "java/lang/String");
172de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    jobjectArray result = (*env)->NewObjectArray(env, 4, stringClass, NULL);
173de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski
174de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    char path[PATH_MAX];
175de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    char* process_path = getcwd(path, sizeof(path));
176de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    char user_dir[PATH_MAX + 10] = "user.dir=";
177de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    strncat(user_dir, process_path, PATH_MAX);
178de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    jstring user_dir_str = (*env)->NewStringUTF(env, user_dir);
179de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    if ((*env)->ExceptionCheck(env)) {
180de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski        return NULL;
181de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    }
182de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    (*env)->SetObjectArrayElement(env, result, 0, user_dir_str);
183de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    if ((*env)->ExceptionCheck(env)) {
184de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski        return NULL;
185de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    }
186de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    jstring zlib_str = (*env)->NewStringUTF(env, "android.zlib.version=" ZLIB_VERSION);
187de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    if ((*env)->ExceptionCheck(env)) {
188de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski        return NULL;
189de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    }
190de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    (*env)->SetObjectArrayElement(env, result, 1, zlib_str);
191de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    if ((*env)->ExceptionCheck(env)) {
192de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski        return NULL;
193de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    }
194de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    jstring ssl_str = (*env)->NewStringUTF(env, "android.openssl.version=" OPENSSL_VERSION_TEXT);
195de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    if ((*env)->ExceptionCheck(env)) {
196de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski        return NULL;
197de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    }
198de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    (*env)->SetObjectArrayElement(env, result, 2, ssl_str);
199de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    if ((*env)->ExceptionCheck(env)) {
200de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski        return NULL;
201de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    }
202de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski
203de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski
204de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    const char* library_path = getenv("LD_LIBRARY_PATH");
20570b617fe562806bc3e15452a2792fec4355bd54fPrzemyslaw Szczepaniak#if defined(__ANDROID__)
206de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    if (library_path == NULL) {
207de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski        android_get_LD_LIBRARY_PATH(path, sizeof(path));
208de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski        library_path = path;
209de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    }
210de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski#endif
211de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    if (library_path == NULL) {
212de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski        library_path = "";
213de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    }
214de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    char* java_path = malloc(strlen("java.library.path=") + strlen(library_path) + 1);
215de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    strcpy(java_path, "java.library.path=");
216de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    strcat(java_path, library_path);
217de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    jstring java_path_str = (*env)->NewStringUTF(env, java_path);
218de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    free((void*)java_path);
219de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    if ((*env)->ExceptionCheck(env)) {
220de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski        return NULL;
221de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    }
222de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    (*env)->SetObjectArrayElement(env, result, 3, java_path_str);
223de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    if ((*env)->ExceptionCheck(env)) {
224de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski        return NULL;
225de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    }
226de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski
227de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    return result;
228de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski}
229de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski
230de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebskistatic void System_log(JNIEnv* env, jclass ignored, jchar type, jstring javaMessage, jthrowable exception) {
231de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    int priority;
232de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    switch (type) {
233de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    case 'D': case 'd': priority = ANDROID_LOG_DEBUG;   break;
234de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    case 'E': case 'e': priority = ANDROID_LOG_ERROR;   break;
235de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    case 'F': case 'f': priority = ANDROID_LOG_FATAL;   break;
236de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    case 'I': case 'i': priority = ANDROID_LOG_INFO;    break;
237de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    case 'S': case 's': priority = ANDROID_LOG_SILENT;  break;
238de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    case 'V': case 'v': priority = ANDROID_LOG_VERBOSE; break;
239de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    case 'W': case 'w': priority = ANDROID_LOG_WARN;    break;
240de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    default:            priority = ANDROID_LOG_DEFAULT; break;
241de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    }
2423f64b8777d7358c99dd201bd01a9444786cb91b0Narayan Kamath
2433f64b8777d7358c99dd201bd01a9444786cb91b0Narayan Kamath    WITH_PLATFORM_STRING(env, javaMessage, message) {
2443f64b8777d7358c99dd201bd01a9444786cb91b0Narayan Kamath      if (message == NULL) {
2453f64b8777d7358c99dd201bd01a9444786cb91b0Narayan Kamath          // Since this function is used for last-gasp debugging output, be noisy on failure.
2463f64b8777d7358c99dd201bd01a9444786cb91b0Narayan Kamath          return;
2473f64b8777d7358c99dd201bd01a9444786cb91b0Narayan Kamath      }
2483f64b8777d7358c99dd201bd01a9444786cb91b0Narayan Kamath      LOG_PRI(priority, "System", "%s", message);
2493f64b8777d7358c99dd201bd01a9444786cb91b0Narayan Kamath    } END_PLATFORM_STRING(env, message);
2503f64b8777d7358c99dd201bd01a9444786cb91b0Narayan Kamath
251de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    if (exception != NULL) {
25284f76c530401aa1e6e0fd4020af952421a31f77fNarayan Kamath        jniLogException(env, priority, "System", exception);
253de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski    }
254de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski}
255de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski
2568e35578afea87c4f7a8ffc0931de13bd57e82fb2Narayan Kamathstatic jlong System_nanoTime(JNIEnv* env, jclass unused) {
2578e35578afea87c4f7a8ffc0931de13bd57e82fb2Narayan Kamath  struct timespec now;
2588e35578afea87c4f7a8ffc0931de13bd57e82fb2Narayan Kamath  clock_gettime(CLOCK_MONOTONIC, &now);
2598e35578afea87c4f7a8ffc0931de13bd57e82fb2Narayan Kamath  return now.tv_sec * 1000000000LL + now.tv_nsec;
2608e35578afea87c4f7a8ffc0931de13bd57e82fb2Narayan Kamath}
2618e35578afea87c4f7a8ffc0931de13bd57e82fb2Narayan Kamath
2628e35578afea87c4f7a8ffc0931de13bd57e82fb2Narayan Kamathstatic jlong System_currentTimeMillis(JNIEnv* env, jclass unused) {
2638e35578afea87c4f7a8ffc0931de13bd57e82fb2Narayan Kamath  return JVM_CurrentTimeMillis(NULL, NULL);
2648e35578afea87c4f7a8ffc0931de13bd57e82fb2Narayan Kamath}
2658e35578afea87c4f7a8ffc0931de13bd57e82fb2Narayan Kamath
266de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebskistatic JNINativeMethod gMethods[] = {
267de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski  NATIVE_METHOD(System, mapLibraryName, "(Ljava/lang/String;)Ljava/lang/String;"),
268de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski  NATIVE_METHOD(System, setErr0, "(Ljava/io/PrintStream;)V"),
269de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski  NATIVE_METHOD(System, setOut0, "(Ljava/io/PrintStream;)V"),
270de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski  NATIVE_METHOD(System, setIn0, "(Ljava/io/InputStream;)V"),
271de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski  NATIVE_METHOD(System, specialProperties, "()[Ljava/lang/String;"),
272de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski  NATIVE_METHOD(System, log, "(CLjava/lang/String;Ljava/lang/Throwable;)V"),
2738e35578afea87c4f7a8ffc0931de13bd57e82fb2Narayan Kamath  NATIVE_METHOD(System, currentTimeMillis, "()J"),
2748e35578afea87c4f7a8ffc0931de13bd57e82fb2Narayan Kamath  NATIVE_METHOD(System, nanoTime, "()J"),
275de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski};
276de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski
277de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebskivoid register_java_lang_System(JNIEnv* env) {
278de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski  jniRegisterNativeMethods(env, "java/lang/System", gMethods, NELEM(gMethods));
279de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski}
280