126 }
127
128 private static class CheckedEntrySet
129 extends AbstractSet<Map.Entry<String,String>>
130 {
131 private final Set<Map.Entry<String,String>> s;
132 public CheckedEntrySet(Set<Map.Entry<String,String>> s) {this.s = s;}
133 public int size() {return s.size();}
134 public boolean isEmpty() {return s.isEmpty();}
135 public void clear() { s.clear();}
136 public Iterator<Map.Entry<String,String>> iterator() {
137 return new Iterator<Map.Entry<String,String>>() {
138 Iterator<Map.Entry<String,String>> i = s.iterator();
139 public boolean hasNext() { return i.hasNext();}
140 public Map.Entry<String,String> next() {
141 return new CheckedEntry(i.next());
142 }
143 public void remove() { i.remove();}
144 };
145 }
146 private static Map.Entry<String,String> checkedEntry (Object o) {
147 Map.Entry<String,String> e = (Map.Entry<String,String>) o;
148 nonNullString(e.getKey());
149 nonNullString(e.getValue());
150 return e;
151 }
152 public boolean contains(Object o) {return s.contains(checkedEntry(o));}
153 public boolean remove(Object o) {return s.remove(checkedEntry(o));}
154 }
155
156 private static class CheckedValues extends AbstractCollection<String> {
157 private final Collection<String> c;
158 public CheckedValues(Collection<String> c) {this.c = c;}
159 public int size() {return c.size();}
160 public boolean isEmpty() {return c.isEmpty();}
161 public void clear() { c.clear();}
162 public Iterator<String> iterator() {return c.iterator();}
163 public boolean contains(Object o) {return c.contains(nonNullString(o));}
164 public boolean remove(Object o) {return c.remove(nonNullString(o));}
165 }
166
275 return theCaseInsensitiveEnvironment.get(name);
276 }
277
278 // Only for use by System.getenv()
279 static Map<String,String> getenv() {
280 return theUnmodifiableEnvironment;
281 }
282
283 // Only for use by ProcessBuilder.environment()
284 static Map<String,String> environment() {
285 return (Map<String,String>) theEnvironment.clone();
286 }
287
288 // Only for use by Runtime.exec(...String[]envp...)
289 static Map<String,String> emptyEnvironment(int capacity) {
290 return new ProcessEnvironment(capacity);
291 }
292
293 private static native String environmentBlock();
294
295 // Only for use by ProcessImpl.start()
296 String toEnvironmentBlock() {
297 // Sort Unicode-case-insensitively by name
298 List<Map.Entry<String,String>> list = new ArrayList<>(entrySet());
299 Collections.sort(list, entryComparator);
300
301 StringBuilder sb = new StringBuilder(size()*30);
302 for (Map.Entry<String,String> e : list)
303 sb.append(e.getKey())
304 .append('=')
305 .append(e.getValue())
306 .append('\u0000');
307 // Ensure double NUL termination,
308 // even if environment is empty.
309 if (sb.length() == 0)
310 sb.append('\u0000');
311 sb.append('\u0000');
312 return sb.toString();
313 }
314
315 static String toEnvironmentBlock(Map<String,String> map) {
316 return map == null ? null :
317 ((ProcessEnvironment)map).toEnvironmentBlock();
318 }
319 }
|
126 }
127
128 private static class CheckedEntrySet
129 extends AbstractSet<Map.Entry<String,String>>
130 {
131 private final Set<Map.Entry<String,String>> s;
132 public CheckedEntrySet(Set<Map.Entry<String,String>> s) {this.s = s;}
133 public int size() {return s.size();}
134 public boolean isEmpty() {return s.isEmpty();}
135 public void clear() { s.clear();}
136 public Iterator<Map.Entry<String,String>> iterator() {
137 return new Iterator<Map.Entry<String,String>>() {
138 Iterator<Map.Entry<String,String>> i = s.iterator();
139 public boolean hasNext() { return i.hasNext();}
140 public Map.Entry<String,String> next() {
141 return new CheckedEntry(i.next());
142 }
143 public void remove() { i.remove();}
144 };
145 }
146 private static Map.Entry<String,String> checkedEntry(Object o) {
147 Map.Entry<String,String> e = (Map.Entry<String,String>) o;
148 nonNullString(e.getKey());
149 nonNullString(e.getValue());
150 return e;
151 }
152 public boolean contains(Object o) {return s.contains(checkedEntry(o));}
153 public boolean remove(Object o) {return s.remove(checkedEntry(o));}
154 }
155
156 private static class CheckedValues extends AbstractCollection<String> {
157 private final Collection<String> c;
158 public CheckedValues(Collection<String> c) {this.c = c;}
159 public int size() {return c.size();}
160 public boolean isEmpty() {return c.isEmpty();}
161 public void clear() { c.clear();}
162 public Iterator<String> iterator() {return c.iterator();}
163 public boolean contains(Object o) {return c.contains(nonNullString(o));}
164 public boolean remove(Object o) {return c.remove(nonNullString(o));}
165 }
166
275 return theCaseInsensitiveEnvironment.get(name);
276 }
277
278 // Only for use by System.getenv()
279 static Map<String,String> getenv() {
280 return theUnmodifiableEnvironment;
281 }
282
283 // Only for use by ProcessBuilder.environment()
284 static Map<String,String> environment() {
285 return (Map<String,String>) theEnvironment.clone();
286 }
287
288 // Only for use by Runtime.exec(...String[]envp...)
289 static Map<String,String> emptyEnvironment(int capacity) {
290 return new ProcessEnvironment(capacity);
291 }
292
293 private static native String environmentBlock();
294
295 // Some versions of MSVCRT.DLL require SystemRoot to be set.
296 // So, we make sure that it is always set, even if not provided
297 // by the caller.
298 private final static String SYSTEMROOT = "SystemRoot";
299
300 // Only for use by ProcessImpl.start()
301 String toEnvironmentBlock() {
302 // Sort Unicode-case-insensitively by name
303 List<Map.Entry<String,String>> list = new ArrayList<>(entrySet());
304 Collections.sort(list, entryComparator);
305
306 StringBuilder sb = new StringBuilder(size()*30);
307 int cmp = -1;
308
309 for (Map.Entry<String,String> e : list) {
310 String key = e.getKey();
311 String value = e.getValue();
312 if (cmp < 0 && (cmp = nameComparator.compare(key, SYSTEMROOT)) > 0) {
313 // Not set, so add it here
314 addToEnvIfSet(sb, SYSTEMROOT);
315 }
316 addToEnv(sb, key, value);
317 }
318 if (cmp < 0) {
319 // Got to end of list and still not found
320 addToEnvIfSet(sb, SYSTEMROOT);
321 }
322 if (sb.length() == 0) {
323 // Environment was empty and SystemRoot not set in parent
324 sb.append('\u0000');
325 }
326 return sb.toString();
327 }
328
329 // add the environment variable to the child, if it exists in parent
330 private static void addToEnvIfSet(StringBuilder sb, String name) {
331 String s = getenv(name);
332 if (s != null)
333 addToEnv(sb, name, s);
334 }
335
336 private static void addToEnv(StringBuilder sb, String name, String val) {
337 sb.append(name+"="+val+'\u0000');
338 }
339
340 static String toEnvironmentBlock(Map<String,String> map) {
341 return map == null ? null :
342 ((ProcessEnvironment)map).toEnvironmentBlock();
343 }
344 }
|