Zygote.java revision 973b4663b0b5ee62006522bf4742af076096e548
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.internal.os; 18 19 20import dalvik.system.ZygoteHooks; 21import libcore.io.ErrnoException; 22import libcore.io.Libcore; 23 24/** @hide */ 25public final class Zygote { 26 /* 27 * Bit values for "debugFlags" argument. The definitions are duplicated 28 * in the native code. 29 */ 30 31 /** enable debugging over JDWP */ 32 public static final int DEBUG_ENABLE_DEBUGGER = 1; 33 /** enable JNI checks */ 34 public static final int DEBUG_ENABLE_CHECKJNI = 1 << 1; 35 /** enable Java programming language "assert" statements */ 36 public static final int DEBUG_ENABLE_ASSERT = 1 << 2; 37 /** disable the JIT compiler */ 38 public static final int DEBUG_ENABLE_SAFEMODE = 1 << 3; 39 /** Enable logging of third-party JNI activity. */ 40 public static final int DEBUG_ENABLE_JNI_LOGGING = 1 << 4; 41 42 /** No external storage should be mounted. */ 43 public static final int MOUNT_EXTERNAL_NONE = 0; 44 /** Single-user external storage should be mounted. */ 45 public static final int MOUNT_EXTERNAL_SINGLEUSER = 1; 46 /** Multi-user external storage should be mounted. */ 47 public static final int MOUNT_EXTERNAL_MULTIUSER = 2; 48 /** All multi-user external storage should be mounted. */ 49 public static final int MOUNT_EXTERNAL_MULTIUSER_ALL = 3; 50 51 private static final ZygoteHooks VM_HOOKS = new ZygoteHooks(); 52 53 private Zygote() {} 54 55 /** 56 * Forks a new VM instance. The current VM must have been started 57 * with the -Xzygote flag. <b>NOTE: new instance keeps all 58 * root capabilities. The new process is expected to call capset()</b>. 59 * 60 * @param uid the UNIX uid that the new process should setuid() to after 61 * fork()ing and and before spawning any threads. 62 * @param gid the UNIX gid that the new process should setgid() to after 63 * fork()ing and and before spawning any threads. 64 * @param gids null-ok; a list of UNIX gids that the new process should 65 * setgroups() to after fork and before spawning any threads. 66 * @param debugFlags bit flags that enable debugging features. 67 * @param rlimits null-ok an array of rlimit tuples, with the second 68 * dimension having a length of 3 and representing 69 * (resource, rlim_cur, rlim_max). These are set via the posix 70 * setrlimit(2) call. 71 * @param seInfo null-ok a string specifying SELinux information for 72 * the new process. 73 * @param niceName null-ok a string specifying the process name. 74 * @param fdsToClose an array of ints, holding one or more POSIX 75 * file descriptor numbers that are to be closed by the child 76 * (and replaced by /dev/null) after forking. An integer value 77 * of -1 in any entry in the array means "ignore this one". 78 * 79 * @return 0 if this is the child, pid of the child 80 * if this is the parent, or -1 on error. 81 */ 82 public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags, 83 int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose) { 84 VM_HOOKS.preFork(); 85 int pid = nativeForkAndSpecialize( 86 uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose); 87 VM_HOOKS.postForkCommon(); 88 return pid; 89 } 90 91 native private static int nativeForkAndSpecialize(int uid, int gid, int[] gids,int debugFlags, 92 int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose); 93 94 /** 95 * Special method to start the system server process. In addition to the 96 * common actions performed in forkAndSpecialize, the pid of the child 97 * process is recorded such that the death of the child process will cause 98 * zygote to exit. 99 * 100 * @param uid the UNIX uid that the new process should setuid() to after 101 * fork()ing and and before spawning any threads. 102 * @param gid the UNIX gid that the new process should setgid() to after 103 * fork()ing and and before spawning any threads. 104 * @param gids null-ok; a list of UNIX gids that the new process should 105 * setgroups() to after fork and before spawning any threads. 106 * @param debugFlags bit flags that enable debugging features. 107 * @param rlimits null-ok an array of rlimit tuples, with the second 108 * dimension having a length of 3 and representing 109 * (resource, rlim_cur, rlim_max). These are set via the posix 110 * setrlimit(2) call. 111 * @param permittedCapabilities argument for setcap() 112 * @param effectiveCapabilities argument for setcap() 113 * 114 * @return 0 if this is the child, pid of the child 115 * if this is the parent, or -1 on error. 116 */ 117 public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags, 118 int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) { 119 VM_HOOKS.preFork(); 120 int pid = nativeForkSystemServer( 121 uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities); 122 VM_HOOKS.postForkCommon(); 123 return pid; 124 } 125 126 native private static int nativeForkSystemServer(int uid, int gid, int[] gids, int debugFlags, 127 int[][] rlimits, long permittedCapabilities, long effectiveCapabilities); 128 129 private static void callPostForkChildHooks(int debugFlags) { 130 VM_HOOKS.postForkChild(debugFlags); 131 } 132 133 134 /** 135 * Executes "/system/bin/sh -c <command>" using the exec() system call. 136 * This method throws a runtime exception if exec() failed, otherwise, this 137 * method never returns. 138 * 139 * @param command The shell command to execute. 140 */ 141 public static void execShell(String command) { 142 String[] args = { "/system/bin/sh", "-c", command }; 143 try { 144 Libcore.os.execv(args[0], args); 145 } catch (ErrnoException e) { 146 throw new RuntimeException(e); 147 } 148 } 149 150 /** 151 * Appends quotes shell arguments to the specified string builder. 152 * The arguments are quoted using single-quotes, escaped if necessary, 153 * prefixed with a space, and appended to the command. 154 * 155 * @param command A string builder for the shell command being constructed. 156 * @param args An array of argument strings to be quoted and appended to the command. 157 * @see #execShell(String) 158 */ 159 public static void appendQuotedShellArgs(StringBuilder command, String[] args) { 160 for (String arg : args) { 161 command.append(" '").append(arg.replace("'", "'\\''")).append("'"); 162 } 163 } 164} 165