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