151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 2003, 2004, 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
2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include <stdlib.h>
2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include <string.h>
2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include "jni.h"
2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include "jni_util.h"
3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifdef __APPLE__
3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#include <crt_externs.h>
3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#define environ (*_NSGetEnviron())
3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif
35cab01ac294bb8ded259851673baa4c6ca226f828Steven Moreland#include <nativehelper/JNIHelp.h>
36de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski
37de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski#define NATIVE_METHOD(className, functionName, signature) \
38de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski{ #functionName, signature, (void*)(className ## _ ## functionName) }
3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr JastrzebskiJNIEXPORT jobjectArray JNICALL
41de626ec8a109ea18283d96c720cc57e2f32f67faPiotr JastrzebskiProcessEnvironment_environ(JNIEnv *env, jclass ign)
4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{
4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /* This is one of the rare times it's more portable to declare an
4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * external symbol explicitly, rather than via a system header.
4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The declaration is standardized as part of UNIX98, but there is
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * no standard (not even de-facto) header file where the
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * declaration is to be found.  See:
4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * http://www.opengroup.org/onlinepubs/007908799/xbd/envvar.html */
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#ifndef __APPLE__
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    extern char ** environ; /* environ[i] looks like: VAR=VALUE\0 */
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski#endif
5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    jsize count = 0;
5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    jsize i, j;
5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    jobjectArray result;
5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    jclass byteArrCls = (*env)->FindClass(env, "[B");
5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    for (i = 0; environ[i]; i++) {
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /* Ignore corrupted environment variables */
6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (strchr(environ[i], '=') != NULL)
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            count++;
6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    result = (*env)->NewObjectArray(env, 2*count, byteArrCls, 0);
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    if (result == NULL) return NULL;
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    for (i = 0, j = 0; environ[i]; i++) {
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        const char * varEnd = strchr(environ[i], '=');
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /* Ignore corrupted environment variables */
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (varEnd != NULL) {
7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            jbyteArray var, val;
7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            const char * valBeg = varEnd + 1;
7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            jsize varLength = varEnd - environ[i];
7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            jsize valLength = strlen(valBeg);
7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            var = (*env)->NewByteArray(env, varLength);
7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (var == NULL) return NULL;
7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            val = (*env)->NewByteArray(env, valLength);
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (val == NULL) return NULL;
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            (*env)->SetByteArrayRegion(env, var, 0, varLength,
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                       (jbyte*) environ[i]);
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            (*env)->SetByteArrayRegion(env, val, 0, valLength,
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                       (jbyte*) valBeg);
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            (*env)->SetObjectArrayElement(env, result, 2*j  , var);
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            (*env)->SetObjectArrayElement(env, result, 2*j+1, val);
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            (*env)->DeleteLocalRef(env, var);
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            (*env)->DeleteLocalRef(env, val);
8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            j++;
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    return result;
9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
93de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski
94de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebskistatic JNINativeMethod gMethods[] = {
95de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski  NATIVE_METHOD(ProcessEnvironment, environ, "()[[B"),
96de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski};
97de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski
98de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebskivoid register_java_lang_ProcessEnvironment(JNIEnv* env) {
99de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski  jniRegisterNativeMethods(env, "java/lang/ProcessEnvironment", gMethods, NELEM(gMethods));
100de626ec8a109ea18283d96c720cc57e2f32f67faPiotr Jastrzebski}
101