/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* We use APIs that access a so-called Windows "Environment Block",
* which looks like an array of jchars like this:
*
* 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
* native Windows APIs.
*
* 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
* @since 1.5
*/
{
// An initial `=' indicates a magic Windows variable name -- OK
throw new IllegalArgumentException
return name;
}
throw new IllegalArgumentException
return value;
}
if (o == null)
throw new NullPointerException();
return (String) o;
}
}
}
}
}
}
private static class CheckedEntry
{
}
}
private static class CheckedEntrySet
{
return new CheckedEntry(i.next());
}
};
}
nonNullString(e.getKey());
nonNullString(e.getValue());
return e;
}
}
private final Collection<String> c;
}
}
return new CheckedKeySet(super.keySet());
}
return new CheckedValues(super.values());
}
return new CheckedEntrySet(super.entrySet());
}
private static final class NameComparator
implements Comparator<String> {
// 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
}
}
}
}
private static final class EntryComparator
}
}
// Allow `=' as first char in name, e.g. =C:=C:\DIR
static {
nameComparator = new NameComparator();
entryComparator = new EntryComparator();
theEnvironment = new ProcessEnvironment();
for (beg = 0;
// An initial `=' indicates a magic Windows variable name -- OK
// Ignore corrupted environment strings.
}
}
private ProcessEnvironment() {
super();
}
super(capacity);
}
// 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()
return theUnmodifiableEnvironment;
}
// Only for use by ProcessBuilder.environment()
}
// Only for use by ProcessBuilder.environment(String[] envp)
return new ProcessEnvironment(capacity);
}
// Only for use by ProcessImpl.start()
// Sort Unicode-case-insensitively by name
int cmp = -1;
// Some versions of MSVCRT.DLL require SystemRoot to be set.
// So, we make sure that it is always set, even if not provided
// by the caller.
// Not set, so add it here
}
}
if (cmp < 0) {
// Got to end of list and still not found
}
// Environment was empty and SystemRoot not set in parent
}
// Block is double NUL terminated
}
// add the environment variable to the child, if it exists in parent
if (s != null)
}
}
}
}