ProcessEnvironment.java revision 3323
2362N/A * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 0N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 0N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 2362N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 0N/A * or visit www.oracle.com if you need additional information or have any 0N/A/* We use APIs that access a so-called Windows "Environment Block", 0N/A * which looks like an array of jchars like this: 0N/A * FOO=BAR\u0000 ... GORP=QUUX\u0000\u0000 * This data structure has a number of peculiarities we must contend with: * - The NUL jchar separators, and a double NUL jchar terminator. * It appears that the Windows implementation requires double NUL * termination even if the environment is empty. We should always * generate environments with double NUL termination, while accepting * empty environments consisting of a single NUL. * - on Windows9x, this is actually an array of 8-bit chars, not jchars, * encoded in the system default encoding. * - The block must be sorted by Unicode value, case-insensitively, * as if folded to upper case. * - There are magic environment variables maintained by Windows * that start with a `=' (!) character. These are used for * Windows drive current directory (e.g. "=C:=C:\WINNT") or the * exit code of the last command (e.g. "=ExitCode=0000001"). * Since Java and non-9x Windows speak the same character set, and * even the same encoding, we don't have to deal with unreliable * conversion to byte streams. Just add a few NUL terminators. * System.getenv(String) is case-insensitive, while System.getenv() * returns a map that is case-sensitive, which is consistent with * The non-private methods in this class are not for general use even * within this package. Instead, they are the system-dependent parts * of the system-independent method of the same name. Don't even * think of using this class unless your method's name appears below. * @author Martin Buchholz // An initial `=' indicates a magic Windows variable name -- OK (
"Invalid environment variable name: \"" +
name +
"\"");
(
"Invalid environment variable value: \"" +
value +
"\"");
// We can't use String.compareToIgnoreCase since it // canonicalizes to lower case, while Windows // canonicalizes to upper case! For example, "_" should // sort *after* "Z", not before. for (
int i =
0; i <
min; i++) {
// No overflow because of numeric promotion // Allow `=' as first char in name, e.g. =C:=C:\DIR // An initial `=' indicates a magic Windows variable name -- OK // Ignore corrupted environment strings. // Only for use by System.getenv(String) // The original implementation used a native call to _wgetenv, // but it turns out that _wgetenv is only consistent with // GetEnvironmentStringsW (for non-ASCII) if `wmain' is used // instead of `main', even in a process created using // CREATE_UNICODE_ENVIRONMENT. Instead we perform the // case-insensitive comparison ourselves. At least this // guarantees that System.getenv().get(String) will be // consistent with System.getenv(String). // Only for use by System.getenv() // Only for use by ProcessBuilder.environment() // Only for use by Runtime.exec(...String[]envp...) // Only for use by ProcessImpl.start() // Sort Unicode-case-insensitively by name // Ensure double NUL termination, // even if environment is empty.