1 | /* |
2 | * Copyright (c) 2003, 2013, 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 | |
26 | #include <stdlib.h> |
27 | #include <string.h> |
28 | #include "jni.h" |
29 | #include "jni_util.h" |
30 | |
31 | #ifdef __APPLE__ |
32 | #include <crt_externs.h> |
33 | #define environ (*_NSGetEnviron()) |
34 | #else |
35 | /* This is one of the rare times it's more portable to declare an |
36 | * external symbol explicitly, rather than via a system header. |
37 | * The declaration is standardized as part of UNIX98, but there is |
38 | * no standard (not even de-facto) header file where the |
39 | * declaration is to be found. See: |
40 | * http://www.opengroup.org/onlinepubs/009695399/functions/environ.html |
41 | * http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_02.html |
42 | * |
43 | * "All identifiers in this volume of IEEE Std 1003.1-2001, except |
44 | * environ, are defined in at least one of the headers" (!) |
45 | */ |
46 | extern char **environ; |
47 | #endif |
48 | |
49 | JNIEXPORT jobjectArray JNICALL |
50 | Java_java_lang_ProcessEnvironment_environ(JNIEnv *env, jclass ign) |
51 | { |
52 | jsize count = 0; |
53 | jsize i, j; |
54 | jobjectArray result; |
55 | jclass byteArrCls = (*env)->FindClass(env, "[B" ); |
56 | CHECK_NULL_RETURN(byteArrCls, NULL); |
57 | |
58 | for (i = 0; environ[i]; i++) { |
59 | /* Ignore corrupted environment variables */ |
60 | if (strchr(environ[i], '=') != NULL) |
61 | count++; |
62 | } |
63 | |
64 | result = (*env)->NewObjectArray(env, 2*count, byteArrCls, 0); |
65 | CHECK_NULL_RETURN(result, NULL); |
66 | |
67 | for (i = 0, j = 0; environ[i]; i++) { |
68 | const char * varEnd = strchr(environ[i], '='); |
69 | /* Ignore corrupted environment variables */ |
70 | if (varEnd != NULL) { |
71 | jbyteArray var, val; |
72 | const char * valBeg = varEnd + 1; |
73 | jsize varLength = varEnd - environ[i]; |
74 | jsize valLength = strlen(valBeg); |
75 | var = (*env)->NewByteArray(env, varLength); |
76 | CHECK_NULL_RETURN(var, NULL); |
77 | val = (*env)->NewByteArray(env, valLength); |
78 | CHECK_NULL_RETURN(val, NULL); |
79 | (*env)->SetByteArrayRegion(env, var, 0, varLength, |
80 | (jbyte*) environ[i]); |
81 | (*env)->SetByteArrayRegion(env, val, 0, valLength, |
82 | (jbyte*) valBeg); |
83 | (*env)->SetObjectArrayElement(env, result, 2*j , var); |
84 | (*env)->SetObjectArrayElement(env, result, 2*j+1, val); |
85 | (*env)->DeleteLocalRef(env, var); |
86 | (*env)->DeleteLocalRef(env, val); |
87 | j++; |
88 | } |
89 | } |
90 | |
91 | return result; |
92 | } |
93 | |