1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. Oracle designates this 9 * particular file as subject to the "Classpath" exception as provided 10 * by Oracle in the LICENSE file that accompanied this code. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23 * or visit www.oracle.com if you need additional information or have any 24 * questions. 25 */ 26 27 package java.lang; 28 29 import dalvik.annotation.optimization.FastNative; 30 import java.io.*; 31 import java.util.StringTokenizer; 32 import sun.reflect.CallerSensitive; 33 import java.lang.ref.FinalizerReference; 34 import java.util.ArrayList; 35 import java.util.List; 36 import dalvik.system.BaseDexClassLoader; 37 import dalvik.system.VMDebug; 38 import dalvik.system.VMStack; 39 import dalvik.system.VMRuntime; 40 import libcore.io.IoUtils; 41 import libcore.io.Libcore; 42 import libcore.util.EmptyArray; 43 import static android.system.OsConstants._SC_NPROCESSORS_CONF; 44 45 /** 46 * Every Java application has a single instance of class 47 * <code>Runtime</code> that allows the application to interface with 48 * the environment in which the application is running. The current 49 * runtime can be obtained from the <code>getRuntime</code> method. 50 * <p> 51 * An application cannot create its own instance of this class. 52 * 53 * @author unascribed 54 * @see java.lang.Runtime#getRuntime() 55 * @since JDK1.0 56 */ 57 58 public class Runtime { 59 private static Runtime currentRuntime = new Runtime(); 60 61 /** 62 * Holds the list of threads to run when the VM terminates 63 */ 64 private List<Thread> shutdownHooks = new ArrayList<Thread>(); 65 66 /** 67 * Reflects whether finalization should be run for all objects 68 * when the VM terminates. 69 */ 70 private static boolean finalizeOnExit; 71 72 /** 73 * Reflects whether we are already shutting down the VM. 74 */ 75 private boolean shuttingDown; 76 77 /** 78 * Reflects whether we are tracing method calls. 79 */ 80 private boolean tracingMethods; 81 nativeExit(int code)82 private static native void nativeExit(int code); 83 84 /** 85 * Returns the runtime object associated with the current Java application. 86 * Most of the methods of class <code>Runtime</code> are instance 87 * methods and must be invoked with respect to the current runtime object. 88 * 89 * @return the <code>Runtime</code> object associated with the current 90 * Java application. 91 */ getRuntime()92 public static Runtime getRuntime() { 93 return currentRuntime; 94 } 95 96 /** Don't let anyone else instantiate this class */ Runtime()97 private Runtime() {} 98 99 /** 100 * Terminates the currently running Java virtual machine by initiating its 101 * shutdown sequence. This method never returns normally. The argument 102 * serves as a status code; by convention, a nonzero status code indicates 103 * abnormal termination. 104 * 105 * <p> The virtual machine's shutdown sequence consists of two phases. In 106 * the first phase all registered {@link #addShutdownHook shutdown hooks}, 107 * if any, are started in some unspecified order and allowed to run 108 * concurrently until they finish. In the second phase all uninvoked 109 * finalizers are run if {@link #runFinalizersOnExit finalization-on-exit} 110 * has been enabled. Once this is done the virtual machine {@link #halt 111 * halts}. 112 * 113 * <p> If this method is invoked after the virtual machine has begun its 114 * shutdown sequence then if shutdown hooks are being run this method will 115 * block indefinitely. If shutdown hooks have already been run and on-exit 116 * finalization has been enabled then this method halts the virtual machine 117 * with the given status code if the status is nonzero; otherwise, it 118 * blocks indefinitely. 119 * 120 * <p> The <tt>{@link System#exit(int) System.exit}</tt> method is the 121 * conventional and convenient means of invoking this method. <p> 122 * 123 * @param status 124 * Termination status. By convention, a nonzero status code 125 * indicates abnormal termination. 126 * 127 * @throws SecurityException 128 * If a security manager is present and its <tt>{@link 129 * SecurityManager#checkExit checkExit}</tt> method does not permit 130 * exiting with the specified status 131 * 132 * @see java.lang.SecurityException 133 * @see java.lang.SecurityManager#checkExit(int) 134 * @see #addShutdownHook 135 * @see #removeShutdownHook 136 * @see #runFinalizersOnExit 137 * @see #halt(int) 138 */ exit(int status)139 public void exit(int status) { 140 // Make sure we don't try this several times 141 synchronized(this) { 142 if (!shuttingDown) { 143 shuttingDown = true; 144 145 Thread[] hooks; 146 synchronized (shutdownHooks) { 147 // create a copy of the hooks 148 hooks = new Thread[shutdownHooks.size()]; 149 shutdownHooks.toArray(hooks); 150 } 151 152 // Start all shutdown hooks concurrently 153 for (Thread hook : hooks) { 154 hook.start(); 155 } 156 157 // Wait for all shutdown hooks to finish 158 for (Thread hook : hooks) { 159 try { 160 hook.join(); 161 } catch (InterruptedException ex) { 162 // Ignore, since we are at VM shutdown. 163 } 164 } 165 166 // Ensure finalization on exit, if requested 167 if (finalizeOnExit) { 168 runFinalization(); 169 } 170 171 // Get out of here finally... 172 nativeExit(status); 173 } 174 } 175 } 176 177 /** 178 * Registers a new virtual-machine shutdown hook. 179 * 180 * <p> The Java virtual machine <i>shuts down</i> in response to two kinds 181 * of events: 182 * 183 * <ul> 184 * 185 * <li> The program <i>exits</i> normally, when the last non-daemon 186 * thread exits or when the <tt>{@link #exit exit}</tt> (equivalently, 187 * {@link System#exit(int) System.exit}) method is invoked, or 188 * 189 * <li> The virtual machine is <i>terminated</i> in response to a 190 * user interrupt, such as typing <tt>^C</tt>, or a system-wide event, 191 * such as user logoff or system shutdown. 192 * 193 * </ul> 194 * 195 * <p> A <i>shutdown hook</i> is simply an initialized but unstarted 196 * thread. When the virtual machine begins its shutdown sequence it will 197 * start all registered shutdown hooks in some unspecified order and let 198 * them run concurrently. When all the hooks have finished it will then 199 * run all uninvoked finalizers if finalization-on-exit has been enabled. 200 * Finally, the virtual machine will halt. Note that daemon threads will 201 * continue to run during the shutdown sequence, as will non-daemon threads 202 * if shutdown was initiated by invoking the <tt>{@link #exit exit}</tt> 203 * method. 204 * 205 * <p> Once the shutdown sequence has begun it can be stopped only by 206 * invoking the <tt>{@link #halt halt}</tt> method, which forcibly 207 * terminates the virtual machine. 208 * 209 * <p> Once the shutdown sequence has begun it is impossible to register a 210 * new shutdown hook or de-register a previously-registered hook. 211 * Attempting either of these operations will cause an 212 * <tt>{@link IllegalStateException}</tt> to be thrown. 213 * 214 * <p> Shutdown hooks run at a delicate time in the life cycle of a virtual 215 * machine and should therefore be coded defensively. They should, in 216 * particular, be written to be thread-safe and to avoid deadlocks insofar 217 * as possible. They should also not rely blindly upon services that may 218 * have registered their own shutdown hooks and therefore may themselves in 219 * the process of shutting down. Attempts to use other thread-based 220 * services such as the AWT event-dispatch thread, for example, may lead to 221 * deadlocks. 222 * 223 * <p> Shutdown hooks should also finish their work quickly. When a 224 * program invokes <tt>{@link #exit exit}</tt> the expectation is 225 * that the virtual machine will promptly shut down and exit. When the 226 * virtual machine is terminated due to user logoff or system shutdown the 227 * underlying operating system may only allow a fixed amount of time in 228 * which to shut down and exit. It is therefore inadvisable to attempt any 229 * user interaction or to perform a long-running computation in a shutdown 230 * hook. 231 * 232 * <p> Uncaught exceptions are handled in shutdown hooks just as in any 233 * other thread, by invoking the <tt>{@link ThreadGroup#uncaughtException 234 * uncaughtException}</tt> method of the thread's <tt>{@link 235 * ThreadGroup}</tt> object. The default implementation of this method 236 * prints the exception's stack trace to <tt>{@link System#err}</tt> and 237 * terminates the thread; it does not cause the virtual machine to exit or 238 * halt. 239 * 240 * <p> In rare circumstances the virtual machine may <i>abort</i>, that is, 241 * stop running without shutting down cleanly. This occurs when the 242 * virtual machine is terminated externally, for example with the 243 * <tt>SIGKILL</tt> signal on Unix or the <tt>TerminateProcess</tt> call on 244 * Microsoft Windows. The virtual machine may also abort if a native 245 * method goes awry by, for example, corrupting internal data structures or 246 * attempting to access nonexistent memory. If the virtual machine aborts 247 * then no guarantee can be made about whether or not any shutdown hooks 248 * will be run. <p> 249 * 250 * @param hook 251 * An initialized but unstarted <tt>{@link Thread}</tt> object 252 * 253 * @throws IllegalArgumentException 254 * If the specified hook has already been registered, 255 * or if it can be determined that the hook is already running or 256 * has already been run 257 * 258 * @throws IllegalStateException 259 * If the virtual machine is already in the process 260 * of shutting down 261 * 262 * @throws SecurityException 263 * If a security manager is present and it denies 264 * <tt>{@link RuntimePermission}("shutdownHooks")</tt> 265 * 266 * @see #removeShutdownHook 267 * @see #halt(int) 268 * @see #exit(int) 269 * @since 1.3 270 */ addShutdownHook(Thread hook)271 public void addShutdownHook(Thread hook) { 272 // Sanity checks 273 if (hook == null) { 274 throw new NullPointerException("hook == null"); 275 } 276 277 if (shuttingDown) { 278 throw new IllegalStateException("VM already shutting down"); 279 } 280 281 if (hook.started) { 282 throw new IllegalArgumentException("Hook has already been started"); 283 } 284 285 synchronized (shutdownHooks) { 286 if (shutdownHooks.contains(hook)) { 287 throw new IllegalArgumentException("Hook already registered."); 288 } 289 290 shutdownHooks.add(hook); 291 } 292 } 293 294 /** 295 * De-registers a previously-registered virtual-machine shutdown hook. <p> 296 * 297 * @param hook the hook to remove 298 * @return <tt>true</tt> if the specified hook had previously been 299 * registered and was successfully de-registered, <tt>false</tt> 300 * otherwise. 301 * 302 * @throws IllegalStateException 303 * If the virtual machine is already in the process of shutting 304 * down 305 * 306 * @throws SecurityException 307 * If a security manager is present and it denies 308 * <tt>{@link RuntimePermission}("shutdownHooks")</tt> 309 * 310 * @see #addShutdownHook 311 * @see #exit(int) 312 * @since 1.3 313 */ removeShutdownHook(Thread hook)314 public boolean removeShutdownHook(Thread hook) { 315 // Sanity checks 316 if (hook == null) { 317 throw new NullPointerException("hook == null"); 318 } 319 320 if (shuttingDown) { 321 throw new IllegalStateException("VM already shutting down"); 322 } 323 324 synchronized (shutdownHooks) { 325 return shutdownHooks.remove(hook); 326 } 327 } 328 329 /** 330 * Forcibly terminates the currently running Java virtual machine. This 331 * method never returns normally. 332 * 333 * <p> This method should be used with extreme caution. Unlike the 334 * <tt>{@link #exit exit}</tt> method, this method does not cause shutdown 335 * hooks to be started and does not run uninvoked finalizers if 336 * finalization-on-exit has been enabled. If the shutdown sequence has 337 * already been initiated then this method does not wait for any running 338 * shutdown hooks or finalizers to finish their work. <p> 339 * 340 * @param status 341 * Termination status. By convention, a nonzero status code 342 * indicates abnormal termination. If the <tt>{@link Runtime#exit 343 * exit}</tt> (equivalently, <tt>{@link System#exit(int) 344 * System.exit}</tt>) method has already been invoked then this 345 * status code will override the status code passed to that method. 346 * 347 * @throws SecurityException 348 * If a security manager is present and its <tt>{@link 349 * SecurityManager#checkExit checkExit}</tt> method does not permit 350 * an exit with the specified status 351 * 352 * @see #exit 353 * @see #addShutdownHook 354 * @see #removeShutdownHook 355 * @since 1.3 356 */ halt(int status)357 public void halt(int status) { 358 nativeExit(status); 359 } 360 361 /** 362 * Enable or disable finalization on exit; doing so specifies that the 363 * finalizers of all objects that have finalizers that have not yet been 364 * automatically invoked are to be run before the Java runtime exits. 365 * By default, finalization on exit is disabled. 366 * 367 * <p>If there is a security manager, 368 * its <code>checkExit</code> method is first called 369 * with 0 as its argument to ensure the exit is allowed. 370 * This could result in a SecurityException. 371 * 372 * @param value true to enable finalization on exit, false to disable 373 * @deprecated This method is inherently unsafe. It may result in 374 * finalizers being called on live objects while other threads are 375 * concurrently manipulating those objects, resulting in erratic 376 * behavior or deadlock. 377 * 378 * @throws SecurityException 379 * if a security manager exists and its <code>checkExit</code> 380 * method doesn't allow the exit. 381 * 382 * @see java.lang.Runtime#exit(int) 383 * @see java.lang.Runtime#gc() 384 * @see java.lang.SecurityManager#checkExit(int) 385 * @since JDK1.1 386 */ 387 @Deprecated runFinalizersOnExit(boolean value)388 public static void runFinalizersOnExit(boolean value) { 389 finalizeOnExit = value; 390 } 391 392 /** 393 * Executes the specified string command in a separate process. 394 * 395 * <p>This is a convenience method. An invocation of the form 396 * <tt>exec(command)</tt> 397 * behaves in exactly the same way as the invocation 398 * <tt>{@link #exec(String, String[], File) exec}(command, null, null)</tt>. 399 * 400 * @param command a specified system command. 401 * 402 * @return A new {@link Process} object for managing the subprocess 403 * 404 * @throws SecurityException 405 * If a security manager exists and its 406 * {@link SecurityManager#checkExec checkExec} 407 * method doesn't allow creation of the subprocess 408 * 409 * @throws IOException 410 * If an I/O error occurs 411 * 412 * @throws NullPointerException 413 * If <code>command</code> is <code>null</code> 414 * 415 * @throws IllegalArgumentException 416 * If <code>command</code> is empty 417 * 418 * @see #exec(String[], String[], File) 419 * @see ProcessBuilder 420 */ exec(String command)421 public Process exec(String command) throws IOException { 422 return exec(command, null, null); 423 } 424 425 /** 426 * Executes the specified string command in a separate process with the 427 * specified environment. 428 * 429 * <p>This is a convenience method. An invocation of the form 430 * <tt>exec(command, envp)</tt> 431 * behaves in exactly the same way as the invocation 432 * <tt>{@link #exec(String, String[], File) exec}(command, envp, null)</tt>. 433 * 434 * @param command a specified system command. 435 * 436 * @param envp array of strings, each element of which 437 * has environment variable settings in the format 438 * <i>name</i>=<i>value</i>, or 439 * <tt>null</tt> if the subprocess should inherit 440 * the environment of the current process. 441 * 442 * @return A new {@link Process} object for managing the subprocess 443 * 444 * @throws SecurityException 445 * If a security manager exists and its 446 * {@link SecurityManager#checkExec checkExec} 447 * method doesn't allow creation of the subprocess 448 * 449 * @throws IOException 450 * If an I/O error occurs 451 * 452 * @throws NullPointerException 453 * If <code>command</code> is <code>null</code>, 454 * or one of the elements of <code>envp</code> is <code>null</code> 455 * 456 * @throws IllegalArgumentException 457 * If <code>command</code> is empty 458 * 459 * @see #exec(String[], String[], File) 460 * @see ProcessBuilder 461 */ exec(String command, String[] envp)462 public Process exec(String command, String[] envp) throws IOException { 463 return exec(command, envp, null); 464 } 465 466 /** 467 * Executes the specified string command in a separate process with the 468 * specified environment and working directory. 469 * 470 * <p>This is a convenience method. An invocation of the form 471 * <tt>exec(command, envp, dir)</tt> 472 * behaves in exactly the same way as the invocation 473 * <tt>{@link #exec(String[], String[], File) exec}(cmdarray, envp, dir)</tt>, 474 * where <code>cmdarray</code> is an array of all the tokens in 475 * <code>command</code>. 476 * 477 * <p>More precisely, the <code>command</code> string is broken 478 * into tokens using a {@link StringTokenizer} created by the call 479 * <code>new {@link StringTokenizer}(command)</code> with no 480 * further modification of the character categories. The tokens 481 * produced by the tokenizer are then placed in the new string 482 * array <code>cmdarray</code>, in the same order. 483 * 484 * @param command a specified system command. 485 * 486 * @param envp array of strings, each element of which 487 * has environment variable settings in the format 488 * <i>name</i>=<i>value</i>, or 489 * <tt>null</tt> if the subprocess should inherit 490 * the environment of the current process. 491 * 492 * @param dir the working directory of the subprocess, or 493 * <tt>null</tt> if the subprocess should inherit 494 * the working directory of the current process. 495 * 496 * @return A new {@link Process} object for managing the subprocess 497 * 498 * @throws SecurityException 499 * If a security manager exists and its 500 * {@link SecurityManager#checkExec checkExec} 501 * method doesn't allow creation of the subprocess 502 * 503 * @throws IOException 504 * If an I/O error occurs 505 * 506 * @throws NullPointerException 507 * If <code>command</code> is <code>null</code>, 508 * or one of the elements of <code>envp</code> is <code>null</code> 509 * 510 * @throws IllegalArgumentException 511 * If <code>command</code> is empty 512 * 513 * @see ProcessBuilder 514 * @since 1.3 515 */ exec(String command, String[] envp, File dir)516 public Process exec(String command, String[] envp, File dir) 517 throws IOException { 518 if (command.length() == 0) 519 throw new IllegalArgumentException("Empty command"); 520 521 StringTokenizer st = new StringTokenizer(command); 522 String[] cmdarray = new String[st.countTokens()]; 523 for (int i = 0; st.hasMoreTokens(); i++) 524 cmdarray[i] = st.nextToken(); 525 return exec(cmdarray, envp, dir); 526 } 527 528 /** 529 * Executes the specified command and arguments in a separate process. 530 * 531 * <p>This is a convenience method. An invocation of the form 532 * <tt>exec(cmdarray)</tt> 533 * behaves in exactly the same way as the invocation 534 * <tt>{@link #exec(String[], String[], File) exec}(cmdarray, null, null)</tt>. 535 * 536 * @param cmdarray array containing the command to call and 537 * its arguments. 538 * 539 * @return A new {@link Process} object for managing the subprocess 540 * 541 * @throws SecurityException 542 * If a security manager exists and its 543 * {@link SecurityManager#checkExec checkExec} 544 * method doesn't allow creation of the subprocess 545 * 546 * @throws IOException 547 * If an I/O error occurs 548 * 549 * @throws NullPointerException 550 * If <code>cmdarray</code> is <code>null</code>, 551 * or one of the elements of <code>cmdarray</code> is <code>null</code> 552 * 553 * @throws IndexOutOfBoundsException 554 * If <code>cmdarray</code> is an empty array 555 * (has length <code>0</code>) 556 * 557 * @see ProcessBuilder 558 */ exec(String cmdarray[])559 public Process exec(String cmdarray[]) throws IOException { 560 return exec(cmdarray, null, null); 561 } 562 563 /** 564 * Executes the specified command and arguments in a separate process 565 * with the specified environment. 566 * 567 * <p>This is a convenience method. An invocation of the form 568 * <tt>exec(cmdarray, envp)</tt> 569 * behaves in exactly the same way as the invocation 570 * <tt>{@link #exec(String[], String[], File) exec}(cmdarray, envp, null)</tt>. 571 * 572 * @param cmdarray array containing the command to call and 573 * its arguments. 574 * 575 * @param envp array of strings, each element of which 576 * has environment variable settings in the format 577 * <i>name</i>=<i>value</i>, or 578 * <tt>null</tt> if the subprocess should inherit 579 * the environment of the current process. 580 * 581 * @return A new {@link Process} object for managing the subprocess 582 * 583 * @throws SecurityException 584 * If a security manager exists and its 585 * {@link SecurityManager#checkExec checkExec} 586 * method doesn't allow creation of the subprocess 587 * 588 * @throws IOException 589 * If an I/O error occurs 590 * 591 * @throws NullPointerException 592 * If <code>cmdarray</code> is <code>null</code>, 593 * or one of the elements of <code>cmdarray</code> is <code>null</code>, 594 * or one of the elements of <code>envp</code> is <code>null</code> 595 * 596 * @throws IndexOutOfBoundsException 597 * If <code>cmdarray</code> is an empty array 598 * (has length <code>0</code>) 599 * 600 * @see ProcessBuilder 601 */ exec(String[] cmdarray, String[] envp)602 public Process exec(String[] cmdarray, String[] envp) throws IOException { 603 return exec(cmdarray, envp, null); 604 } 605 606 607 /** 608 * Executes the specified command and arguments in a separate process with 609 * the specified environment and working directory. 610 * 611 * <p>Given an array of strings <code>cmdarray</code>, representing the 612 * tokens of a command line, and an array of strings <code>envp</code>, 613 * representing "environment" variable settings, this method creates 614 * a new process in which to execute the specified command. 615 * 616 * <p>This method checks that <code>cmdarray</code> is a valid operating 617 * system command. Which commands are valid is system-dependent, 618 * but at the very least the command must be a non-empty list of 619 * non-null strings. 620 * 621 * <p>If <tt>envp</tt> is <tt>null</tt>, the subprocess inherits the 622 * environment settings of the current process. 623 * 624 * <p>A minimal set of system dependent environment variables may 625 * be required to start a process on some operating systems. 626 * As a result, the subprocess may inherit additional environment variable 627 * settings beyond those in the specified environment. 628 * 629 * <p>{@link ProcessBuilder#start()} is now the preferred way to 630 * start a process with a modified environment. 631 * 632 * <p>The working directory of the new subprocess is specified by <tt>dir</tt>. 633 * If <tt>dir</tt> is <tt>null</tt>, the subprocess inherits the 634 * current working directory of the current process. 635 * 636 * <p>If a security manager exists, its 637 * {@link SecurityManager#checkExec checkExec} 638 * method is invoked with the first component of the array 639 * <code>cmdarray</code> as its argument. This may result in a 640 * {@link SecurityException} being thrown. 641 * 642 * <p>Starting an operating system process is highly system-dependent. 643 * Among the many things that can go wrong are: 644 * <ul> 645 * <li>The operating system program file was not found. 646 * <li>Access to the program file was denied. 647 * <li>The working directory does not exist. 648 * </ul> 649 * 650 * <p>In such cases an exception will be thrown. The exact nature 651 * of the exception is system-dependent, but it will always be a 652 * subclass of {@link IOException}. 653 * 654 * 655 * @param cmdarray array containing the command to call and 656 * its arguments. 657 * 658 * @param envp array of strings, each element of which 659 * has environment variable settings in the format 660 * <i>name</i>=<i>value</i>, or 661 * <tt>null</tt> if the subprocess should inherit 662 * the environment of the current process. 663 * 664 * @param dir the working directory of the subprocess, or 665 * <tt>null</tt> if the subprocess should inherit 666 * the working directory of the current process. 667 * 668 * @return A new {@link Process} object for managing the subprocess 669 * 670 * @throws SecurityException 671 * If a security manager exists and its 672 * {@link SecurityManager#checkExec checkExec} 673 * method doesn't allow creation of the subprocess 674 * 675 * @throws IOException 676 * If an I/O error occurs 677 * 678 * @throws NullPointerException 679 * If <code>cmdarray</code> is <code>null</code>, 680 * or one of the elements of <code>cmdarray</code> is <code>null</code>, 681 * or one of the elements of <code>envp</code> is <code>null</code> 682 * 683 * @throws IndexOutOfBoundsException 684 * If <code>cmdarray</code> is an empty array 685 * (has length <code>0</code>) 686 * 687 * @see ProcessBuilder 688 * @since 1.3 689 */ exec(String[] cmdarray, String[] envp, File dir)690 public Process exec(String[] cmdarray, String[] envp, File dir) 691 throws IOException { 692 return new ProcessBuilder(cmdarray) 693 .environment(envp) 694 .directory(dir) 695 .start(); 696 } 697 698 /** 699 * Returns the number of processors available to the Java virtual machine. 700 * 701 * <p> This value may change during a particular invocation of the virtual 702 * machine. Applications that are sensitive to the number of available 703 * processors should therefore occasionally poll this property and adjust 704 * their resource usage appropriately. </p> 705 * 706 * @return the maximum number of processors available to the virtual 707 * machine; never smaller than one 708 * @since 1.4 709 */ availableProcessors()710 public int availableProcessors() { 711 return (int) Libcore.os.sysconf(_SC_NPROCESSORS_CONF); 712 } 713 714 /** 715 * Returns the amount of free memory in the Java Virtual Machine. 716 * Calling the 717 * <code>gc</code> method may result in increasing the value returned 718 * by <code>freeMemory.</code> 719 * 720 * @return an approximation to the total amount of memory currently 721 * available for future allocated objects, measured in bytes. 722 */ 723 @FastNative freeMemory()724 public native long freeMemory(); 725 726 /** 727 * Returns the total amount of memory in the Java virtual machine. 728 * The value returned by this method may vary over time, depending on 729 * the host environment. 730 * <p> 731 * Note that the amount of memory required to hold an object of any 732 * given type may be implementation-dependent. 733 * 734 * @return the total amount of memory currently available for current 735 * and future objects, measured in bytes. 736 */ 737 @FastNative totalMemory()738 public native long totalMemory(); 739 740 /** 741 * Returns the maximum amount of memory that the Java virtual machine will 742 * attempt to use. If there is no inherent limit then the value {@link 743 * java.lang.Long#MAX_VALUE} will be returned. 744 * 745 * @return the maximum amount of memory that the virtual machine will 746 * attempt to use, measured in bytes 747 * @since 1.4 748 */ 749 @FastNative maxMemory()750 public native long maxMemory(); 751 752 /** 753 * Runs the garbage collector. 754 * Calling this method suggests that the Java virtual machine expend 755 * effort toward recycling unused objects in order to make the memory 756 * they currently occupy available for quick reuse. When control 757 * returns from the method call, the virtual machine has made 758 * its best effort to recycle all discarded objects. 759 * <p> 760 * The name <code>gc</code> stands for "garbage 761 * collector". The virtual machine performs this recycling 762 * process automatically as needed, in a separate thread, even if the 763 * <code>gc</code> method is not invoked explicitly. 764 * <p> 765 * The method {@link System#gc()} is the conventional and convenient 766 * means of invoking this method. 767 */ gc()768 public native void gc(); 769 770 /* Wormhole for calling java.lang.ref.Finalizer.runFinalization */ runFinalization0()771 private static native void runFinalization0(); 772 773 /** 774 * Runs the finalization methods of any objects pending finalization. 775 * Calling this method suggests that the Java virtual machine expend 776 * effort toward running the <code>finalize</code> methods of objects 777 * that have been found to be discarded but whose <code>finalize</code> 778 * methods have not yet been run. When control returns from the 779 * method call, the virtual machine has made a best effort to 780 * complete all outstanding finalizations. 781 * <p> 782 * The virtual machine performs the finalization process 783 * automatically as needed, in a separate thread, if the 784 * <code>runFinalization</code> method is not invoked explicitly. 785 * <p> 786 * The method {@link System#runFinalization()} is the conventional 787 * and convenient means of invoking this method. 788 * 789 * @see java.lang.Object#finalize() 790 */ runFinalization()791 public void runFinalization() { 792 VMRuntime.runFinalization(0); 793 } 794 795 /** 796 * Enables/Disables tracing of instructions. 797 * If the <code>boolean</code> argument is <code>true</code>, this 798 * method suggests that the Java virtual machine emit debugging 799 * information for each instruction in the virtual machine as it 800 * is executed. The format of this information, and the file or other 801 * output stream to which it is emitted, depends on the host environment. 802 * The virtual machine may ignore this request if it does not support 803 * this feature. The destination of the trace output is system 804 * dependent. 805 * <p> 806 * If the <code>boolean</code> argument is <code>false</code>, this 807 * method causes the virtual machine to stop performing the 808 * detailed instruction trace it is performing. 809 * 810 * @param on <code>true</code> to enable instruction tracing; 811 * <code>false</code> to disable this feature. 812 */ traceInstructions(boolean on)813 public void traceInstructions(boolean on) { 814 } 815 816 /** 817 * Enables/Disables tracing of method calls. 818 * If the <code>boolean</code> argument is <code>true</code>, this 819 * method suggests that the Java virtual machine emit debugging 820 * information for each method in the virtual machine as it is 821 * called. The format of this information, and the file or other output 822 * stream to which it is emitted, depends on the host environment. The 823 * virtual machine may ignore this request if it does not support 824 * this feature. 825 * <p> 826 * Calling this method with argument false suggests that the 827 * virtual machine cease emitting per-call debugging information. 828 * <p> 829 * Calling this method on Android Lollipop or later (API level >= 21) 830 * with {@code true} argument will cause it to throw an 831 * {@code UnsupportedOperationException}. 832 * 833 * @param on <code>true</code> to enable instruction tracing; 834 * <code>false</code> to disable this feature. 835 */ traceMethodCalls(boolean on)836 public void traceMethodCalls(boolean on) { 837 if (on != tracingMethods) { 838 if (on) { 839 VMDebug.startMethodTracing(); 840 } else { 841 VMDebug.stopMethodTracing(); 842 } 843 tracingMethods = on; 844 } 845 } 846 847 /** 848 * Loads the native library specified by the filename argument. The filename 849 * argument must be an absolute path name. 850 * (for example 851 * <code>Runtime.getRuntime().load("/home/avh/lib/libX11.so");</code>). 852 * 853 * If the filename argument, when stripped of any platform-specific library 854 * prefix, path, and file extension, indicates a library whose name is, 855 * for example, L, and a native library called L is statically linked 856 * with the VM, then the JNI_OnLoad_L function exported by the library 857 * is invoked rather than attempting to load a dynamic library. 858 * A filename matching the argument does not have to exist in the file 859 * system. See the JNI Specification for more details. 860 * 861 * Otherwise, the filename argument is mapped to a native library image in 862 * an implementation-dependent manner. 863 * <p> 864 * First, if there is a security manager, its <code>checkLink</code> 865 * method is called with the <code>filename</code> as its argument. 866 * This may result in a security exception. 867 * <p> 868 * This is similar to the method {@link #loadLibrary(String)}, but it 869 * accepts a general file name as an argument rather than just a library 870 * name, allowing any file of native code to be loaded. 871 * <p> 872 * The method {@link System#load(String)} is the conventional and 873 * convenient means of invoking this method. 874 * 875 * @param filename the file to load. 876 * @exception SecurityException if a security manager exists and its 877 * <code>checkLink</code> method doesn't allow 878 * loading of the specified dynamic library 879 * @exception UnsatisfiedLinkError if either the filename is not an 880 * absolute path name, the native library is not statically 881 * linked with the VM, or the library cannot be mapped to 882 * a native library image by the host system. 883 * @exception NullPointerException if <code>filename</code> is 884 * <code>null</code> 885 * @see java.lang.Runtime#getRuntime() 886 * @see java.lang.SecurityException 887 * @see java.lang.SecurityManager#checkLink(java.lang.String) 888 */ 889 @CallerSensitive load(String filename)890 public void load(String filename) { 891 load0(VMStack.getStackClass1(), filename); 892 } 893 894 /** Check target sdk, if it's higher than N, we throw an UnsupportedOperationException */ checkTargetSdkVersionForLoad(String methodName)895 private void checkTargetSdkVersionForLoad(String methodName) { 896 final int targetSdkVersion = VMRuntime.getRuntime().getTargetSdkVersion(); 897 if (targetSdkVersion > 24) { 898 throw new UnsupportedOperationException(methodName + " is not supported on SDK " + 899 targetSdkVersion); 900 } 901 } 902 903 // Fixes b/25859957 regression. Depending on private methods is bad, mkay. load(String absolutePath, ClassLoader loader)904 void load(String absolutePath, ClassLoader loader) { 905 checkTargetSdkVersionForLoad("java.lang.Runtime#load(String, ClassLoader)"); 906 907 java.lang.System.logE("java.lang.Runtime#load(String, ClassLoader)" + 908 " is private and will be removed in a future Android release"); 909 if (absolutePath == null) { 910 throw new NullPointerException("absolutePath == null"); 911 } 912 String error = doLoad(absolutePath, loader); 913 if (error != null) { 914 throw new UnsatisfiedLinkError(error); 915 } 916 } 917 load0(Class<?> fromClass, String filename)918 synchronized void load0(Class<?> fromClass, String filename) { 919 if (!(new File(filename).isAbsolute())) { 920 throw new UnsatisfiedLinkError( 921 "Expecting an absolute path of the library: " + filename); 922 } 923 if (filename == null) { 924 throw new NullPointerException("filename == null"); 925 } 926 String error = doLoad(filename, fromClass.getClassLoader()); 927 if (error != null) { 928 throw new UnsatisfiedLinkError(error); 929 } 930 } 931 932 /** 933 * Loads the native library specified by the <code>libname</code> 934 * argument. The <code>libname</code> argument must not contain any platform 935 * specific prefix, file extension or path. If a native library 936 * called <code>libname</code> is statically linked with the VM, then the 937 * JNI_OnLoad_<code>libname</code> function exported by the library is invoked. 938 * See the JNI Specification for more details. 939 * 940 * Otherwise, the libname argument is loaded from a system library 941 * location and mapped to a native library image in an implementation- 942 * dependent manner. 943 * <p> 944 * First, if there is a security manager, its <code>checkLink</code> 945 * method is called with the <code>libname</code> as its argument. 946 * This may result in a security exception. 947 * <p> 948 * The method {@link System#loadLibrary(String)} is the conventional 949 * and convenient means of invoking this method. If native 950 * methods are to be used in the implementation of a class, a standard 951 * strategy is to put the native code in a library file (call it 952 * <code>LibFile</code>) and then to put a static initializer: 953 * <blockquote><pre> 954 * static { System.loadLibrary("LibFile"); } 955 * </pre></blockquote> 956 * within the class declaration. When the class is loaded and 957 * initialized, the necessary native code implementation for the native 958 * methods will then be loaded as well. 959 * <p> 960 * If this method is called more than once with the same library 961 * name, the second and subsequent calls are ignored. 962 * 963 * @param libname the name of the library. 964 * @exception SecurityException if a security manager exists and its 965 * <code>checkLink</code> method doesn't allow 966 * loading of the specified dynamic library 967 * @exception UnsatisfiedLinkError if either the libname argument 968 * contains a file path, the native library is not statically 969 * linked with the VM, or the library cannot be mapped to a 970 * native library image by the host system. 971 * @exception NullPointerException if <code>libname</code> is 972 * <code>null</code> 973 * @see java.lang.SecurityException 974 * @see java.lang.SecurityManager#checkLink(java.lang.String) 975 */ 976 @CallerSensitive loadLibrary(String libname)977 public void loadLibrary(String libname) { 978 loadLibrary0(VMStack.getCallingClassLoader(), libname); 979 } 980 981 /** 982 * Temporarily preserved for backward compatibility. Applications call this 983 * method using reflection. 984 * 985 * **** THIS METHOD WILL BE REMOVED IN A FUTURE ANDROID VERSION **** 986 * 987 * http://b/26217329 988 * 989 * @hide 990 */ loadLibrary(String libname, ClassLoader classLoader)991 public void loadLibrary(String libname, ClassLoader classLoader) { 992 checkTargetSdkVersionForLoad("java.lang.Runtime#loadLibrary(String, ClassLoader)"); 993 java.lang.System.logE("java.lang.Runtime#loadLibrary(String, ClassLoader)" + 994 " is private and will be removed in a future Android release"); 995 loadLibrary0(classLoader, libname); 996 } 997 loadLibrary0(ClassLoader loader, String libname)998 synchronized void loadLibrary0(ClassLoader loader, String libname) { 999 if (libname.indexOf((int)File.separatorChar) != -1) { 1000 throw new UnsatisfiedLinkError( 1001 "Directory separator should not appear in library name: " + libname); 1002 } 1003 String libraryName = libname; 1004 if (loader != null) { 1005 String filename = loader.findLibrary(libraryName); 1006 if (filename == null) { 1007 // It's not necessarily true that the ClassLoader used 1008 // System.mapLibraryName, but the default setup does, and it's 1009 // misleading to say we didn't find "libMyLibrary.so" when we 1010 // actually searched for "liblibMyLibrary.so.so". 1011 throw new UnsatisfiedLinkError(loader + " couldn't find \"" + 1012 System.mapLibraryName(libraryName) + "\""); 1013 } 1014 String error = doLoad(filename, loader); 1015 if (error != null) { 1016 throw new UnsatisfiedLinkError(error); 1017 } 1018 return; 1019 } 1020 1021 String filename = System.mapLibraryName(libraryName); 1022 List<String> candidates = new ArrayList<String>(); 1023 String lastError = null; 1024 for (String directory : getLibPaths()) { 1025 String candidate = directory + filename; 1026 candidates.add(candidate); 1027 1028 if (IoUtils.canOpenReadOnly(candidate)) { 1029 String error = doLoad(candidate, loader); 1030 if (error == null) { 1031 return; // We successfully loaded the library. Job done. 1032 } 1033 lastError = error; 1034 } 1035 } 1036 1037 if (lastError != null) { 1038 throw new UnsatisfiedLinkError(lastError); 1039 } 1040 throw new UnsatisfiedLinkError("Library " + libraryName + " not found; tried " + candidates); 1041 } 1042 1043 private volatile String[] mLibPaths = null; 1044 getLibPaths()1045 private String[] getLibPaths() { 1046 if (mLibPaths == null) { 1047 synchronized(this) { 1048 if (mLibPaths == null) { 1049 mLibPaths = initLibPaths(); 1050 } 1051 } 1052 } 1053 return mLibPaths; 1054 } 1055 initLibPaths()1056 private static String[] initLibPaths() { 1057 String javaLibraryPath = System.getProperty("java.library.path"); 1058 if (javaLibraryPath == null) { 1059 return EmptyArray.STRING; 1060 } 1061 String[] paths = javaLibraryPath.split(":"); 1062 // Add a '/' to the end of each directory so we don't have to do it every time. 1063 for (int i = 0; i < paths.length; ++i) { 1064 if (!paths[i].endsWith("/")) { 1065 paths[i] += "/"; 1066 } 1067 } 1068 return paths; 1069 } doLoad(String name, ClassLoader loader)1070 private String doLoad(String name, ClassLoader loader) { 1071 // Android apps are forked from the zygote, so they can't have a custom LD_LIBRARY_PATH, 1072 // which means that by default an app's shared library directory isn't on LD_LIBRARY_PATH. 1073 1074 // The PathClassLoader set up by frameworks/base knows the appropriate path, so we can load 1075 // libraries with no dependencies just fine, but an app that has multiple libraries that 1076 // depend on each other needed to load them in most-dependent-first order. 1077 1078 // We added API to Android's dynamic linker so we can update the library path used for 1079 // the currently-running process. We pull the desired path out of the ClassLoader here 1080 // and pass it to nativeLoad so that it can call the private dynamic linker API. 1081 1082 // We didn't just change frameworks/base to update the LD_LIBRARY_PATH once at the 1083 // beginning because multiple apks can run in the same process and third party code can 1084 // use its own BaseDexClassLoader. 1085 1086 // We didn't just add a dlopen_with_custom_LD_LIBRARY_PATH call because we wanted any 1087 // dlopen(3) calls made from a .so's JNI_OnLoad to work too. 1088 1089 // So, find out what the native library search path is for the ClassLoader in question... 1090 String librarySearchPath = null; 1091 if (loader != null && loader instanceof BaseDexClassLoader) { 1092 BaseDexClassLoader dexClassLoader = (BaseDexClassLoader) loader; 1093 librarySearchPath = dexClassLoader.getLdLibraryPath(); 1094 } 1095 // nativeLoad should be synchronized so there's only one LD_LIBRARY_PATH in use regardless 1096 // of how many ClassLoaders are in the system, but dalvik doesn't support synchronized 1097 // internal natives. 1098 synchronized (this) { 1099 return nativeLoad(name, loader, librarySearchPath); 1100 } 1101 } 1102 1103 // TODO: should be synchronized, but dalvik doesn't support synchronized internal natives. nativeLoad(String filename, ClassLoader loader, String librarySearchPath)1104 private static native String nativeLoad(String filename, ClassLoader loader, 1105 String librarySearchPath); 1106 1107 /** 1108 * Creates a localized version of an input stream. This method takes 1109 * an <code>InputStream</code> and returns an <code>InputStream</code> 1110 * equivalent to the argument in all respects except that it is 1111 * localized: as characters in the local character set are read from 1112 * the stream, they are automatically converted from the local 1113 * character set to Unicode. 1114 * <p> 1115 * If the argument is already a localized stream, it may be returned 1116 * as the result. 1117 * 1118 * @param in InputStream to localize 1119 * @return a localized input stream 1120 * @see java.io.InputStream 1121 * @see java.io.BufferedReader#BufferedReader(java.io.Reader) 1122 * @see java.io.InputStreamReader#InputStreamReader(java.io.InputStream) 1123 * @deprecated As of JDK 1.1, the preferred way to translate a byte 1124 * stream in the local encoding into a character stream in Unicode is via 1125 * the <code>InputStreamReader</code> and <code>BufferedReader</code> 1126 * classes. 1127 */ 1128 @Deprecated getLocalizedInputStream(InputStream in)1129 public InputStream getLocalizedInputStream(InputStream in) { 1130 return in; 1131 } 1132 1133 /** 1134 * Creates a localized version of an output stream. This method 1135 * takes an <code>OutputStream</code> and returns an 1136 * <code>OutputStream</code> equivalent to the argument in all respects 1137 * except that it is localized: as Unicode characters are written to 1138 * the stream, they are automatically converted to the local 1139 * character set. 1140 * <p> 1141 * If the argument is already a localized stream, it may be returned 1142 * as the result. 1143 * 1144 * @deprecated As of JDK 1.1, the preferred way to translate a 1145 * Unicode character stream into a byte stream in the local encoding is via 1146 * the <code>OutputStreamWriter</code>, <code>BufferedWriter</code>, and 1147 * <code>PrintWriter</code> classes. 1148 * 1149 * @param out OutputStream to localize 1150 * @return a localized output stream 1151 * @see java.io.OutputStream 1152 * @see java.io.BufferedWriter#BufferedWriter(java.io.Writer) 1153 * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream) 1154 * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream) 1155 */ 1156 @Deprecated getLocalizedOutputStream(OutputStream out)1157 public OutputStream getLocalizedOutputStream(OutputStream out) { 1158 return out; 1159 } 1160 1161 } 1162