3909N/A * Copyright (c) 2003, 2010, 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 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/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, 0N/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 2362N/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 0N/A * This data structure has a number of peculiarities we must contend with: 0N/A * - The NUL jchar separators, and a double NUL jchar terminator. 0N/A * It appears that the Windows implementation requires double NUL 0N/A * termination even if the environment is empty. We should always 0N/A * generate environments with double NUL termination, while accepting 0N/A * empty environments consisting of a single NUL. 0N/A * - on Windows9x, this is actually an array of 8-bit chars, not jchars, 0N/A * encoded in the system default encoding. 0N/A * - The block must be sorted by Unicode value, case-insensitively, 0N/A * as if folded to upper case. 0N/A * - There are magic environment variables maintained by Windows 0N/A * that start with a `=' (!) character. These are used for 0N/A * Windows drive current directory (e.g. "=C:=C:\WINNT") or the 0N/A * exit code of the last command (e.g. "=ExitCode=0000001"). 0N/A * Since Java and non-9x Windows speak the same character set, and 0N/A * even the same encoding, we don't have to deal with unreliable 0N/A * conversion to byte streams. Just add a few NUL terminators. 0N/A * System.getenv(String) is case-insensitive, while System.getenv() 0N/A * returns a map that is case-sensitive, which is consistent with 0N/A * native Windows APIs. 0N/A * The non-private methods in this class are not for general use even 0N/A * within this package. Instead, they are the system-dependent parts 0N/A * of the system-independent method of the same name. Don't even 0N/A * think of using this class unless your method's name appears below. 0N/A * @author Martin Buchholz 0N/A // An initial `=' indicates a magic Windows variable name -- OK 0N/A (
"Invalid environment variable name: \"" +
name +
"\"");
0N/A (
"Invalid environment variable value: \"" +
value +
"\"");
0N/A // We can't use String.compareToIgnoreCase since it 0N/A // canonicalizes to lower case, while Windows 0N/A // canonicalizes to upper case! For example, "_" should 0N/A // sort *after* "Z", not before. 0N/A for (
int i =
0; i <
min; i++) {
0N/A // No overflow because of numeric promotion 0N/A // Allow `=' as first char in name, e.g. =C:=C:\DIR 0N/A // An initial `=' indicates a magic Windows variable name -- OK 0N/A // Ignore corrupted environment strings. 0N/A // Only for use by System.getenv(String) 0N/A // The original implementation used a native call to _wgetenv, 0N/A // but it turns out that _wgetenv is only consistent with 0N/A // GetEnvironmentStringsW (for non-ASCII) if `wmain' is used 0N/A // instead of `main', even in a process created using 0N/A // CREATE_UNICODE_ENVIRONMENT. Instead we perform the 0N/A // case-insensitive comparison ourselves. At least this 0N/A // guarantees that System.getenv().get(String) will be 0N/A // consistent with System.getenv(String). 0N/A // Only for use by System.getenv() 0N/A // Only for use by ProcessBuilder.environment() 4103N/A // Only for use by ProcessBuilder.environment(String[] envp) 0N/A // Only for use by ProcessImpl.start() 0N/A // Sort Unicode-case-insensitively by name 4103N/A // Some versions of MSVCRT.DLL require SystemRoot to be set. 4103N/A // So, we make sure that it is always set, even if not provided 4103N/A // Got to end of list and still not found 4103N/A // Environment was empty and SystemRoot not set in parent 4103N/A // Block is double NUL terminated 4103N/A // add the environment variable to the child, if it exists in parent