示例#1
0
  /**
   * Handles post-fork cleanup of parent proc
   *
   * @param pid != 0; pid of child if > 0 or indication of failed fork if < 0;
   * @param descriptors null-ok; file descriptors for child's new stdio if specified.
   * @param pipeFd null-ok; pipe for communication with child.
   * @param parsedArgs non-null; zygote args
   * @return true for "exit command loop" and false for "continue command loop"
   */
  private boolean handleParentProc(
      int pid, FileDescriptor[] descriptors, FileDescriptor pipeFd, Arguments parsedArgs) {

    if (pid > 0) {
      setChildPgid(pid);
    }

    if (descriptors != null) {
      for (FileDescriptor fd : descriptors) {
        IoUtils.closeQuietly(fd);
      }
    }

    boolean usingWrapper = false;
    if (pipeFd != null && pid > 0) {
      DataInputStream is = new DataInputStream(new FileInputStream(pipeFd));
      int innerPid = -1;
      try {
        innerPid = is.readInt();
      } catch (IOException ex) {
        Log.w(TAG, "Error reading pid from wrapped process, child may have died", ex);
      } finally {
        try {
          is.close();
        } catch (IOException ex) {
        }
      }

      // Ensure that the pid reported by the wrapped process is either the
      // child process that we forked, or a descendant of it.
      if (innerPid > 0) {
        int parentPid = innerPid;
        while (parentPid > 0 && parentPid != pid) {
          parentPid = Process.getParentPid(parentPid);
        }
        if (parentPid > 0) {
          Log.i(TAG, "Wrapped process has pid " + innerPid);
          pid = innerPid;
          usingWrapper = true;
        } else {
          Log.w(
              TAG,
              "Wrapped process reported a pid that is not a child of "
                  + "the process that we forked: childPid="
                  + pid
                  + " innerPid="
                  + innerPid);
        }
      }
    }

    try {
      mSocketOutStream.writeInt(pid);
      mSocketOutStream.writeBoolean(usingWrapper);
    } catch (IOException ex) {
      Log.e(TAG, "Error reading from command socket", ex);
      return true;
    }

    /*
     * If the peer wants to use the socket to wait on the
     * newly spawned process, then we're all done.
     */
    if (parsedArgs.peerWait) {
      try {
        mSocket.close();
      } catch (IOException ex) {
        Log.e(TAG, "Zygote: error closing sockets", ex);
      }
      return true;
    }
    return false;
  }