コード例 #1
0
  /**
   * Reads one start command from the command socket. If successful, a child is forked and a {@link
   * ZygoteInit.MethodAndArgsCaller} exception is thrown in that child while in the parent process,
   * the method returns normally. On failure, the child is not spawned and messages are printed to
   * the log and stderr. Returns a boolean status value indicating whether an end-of-file on the
   * command socket has been encountered.
   *
   * @return false if command socket should continue to be read from, or true if an end-of-file has
   *     been encountered.
   * @throws ZygoteInit.MethodAndArgsCaller trampoline to invoke main() method in child process
   */
  boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {

    String args[];
    Arguments parsedArgs = null;
    FileDescriptor[] descriptors;

    try {
      args = readArgumentList();
      descriptors = mSocket.getAncillaryFileDescriptors();
    } catch (IOException ex) {
      Log.w(TAG, "IOException on command socket " + ex.getMessage());
      closeSocket();
      return true;
    }

    if (args == null) {
      // EOF reached.
      closeSocket();
      return true;
    }

    /** the stderr of the most recent request, if avail */
    PrintStream newStderr = null;

    if (descriptors != null && descriptors.length >= 3) {
      newStderr = new PrintStream(new FileOutputStream(descriptors[2]));
    }

    int pid = -1;
    FileDescriptor childPipeFd = null;
    FileDescriptor serverPipeFd = null;

    try {
      parsedArgs = new Arguments(args);

      applyUidSecurityPolicy(parsedArgs, peer);
      applyRlimitSecurityPolicy(parsedArgs, peer);
      applyCapabilitiesSecurityPolicy(parsedArgs, peer);
      applyInvokeWithSecurityPolicy(parsedArgs, peer);

      applyDebuggerSystemProperty(parsedArgs);
      applyInvokeWithSystemProperty(parsedArgs);

      int[][] rlimits = null;

      if (parsedArgs.rlimits != null) {
        rlimits = parsedArgs.rlimits.toArray(intArray2d);
      }

      if (parsedArgs.runtimeInit && parsedArgs.invokeWith != null) {
        FileDescriptor[] pipeFds = Libcore.os.pipe();
        childPipeFd = pipeFds[1];
        serverPipeFd = pipeFds[0];
        ZygoteInit.setCloseOnExec(serverPipeFd, true);
      }

      pid =
          Zygote.forkAndSpecialize(
              parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, rlimits);
    } catch (IOException ex) {
      logAndPrintError(newStderr, "Exception creating pipe", ex);
    } catch (ErrnoException ex) {
      logAndPrintError(newStderr, "Exception creating pipe", ex);
    } catch (IllegalArgumentException ex) {
      logAndPrintError(newStderr, "Invalid zygote arguments", ex);
    } catch (ZygoteSecurityException ex) {
      logAndPrintError(newStderr, "Zygote security policy prevents request: ", ex);
    }

    try {
      if (pid == 0) {
        // in child
        IoUtils.closeQuietly(serverPipeFd);
        serverPipeFd = null;
        handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);

        // should never get here, the child is expected to either
        // throw ZygoteInit.MethodAndArgsCaller or exec().
        return true;
      } else {
        // in parent...pid of < 0 means failure
        IoUtils.closeQuietly(childPipeFd);
        childPipeFd = null;
        return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
      }
    } finally {
      IoUtils.closeQuietly(childPipeFd);
      IoUtils.closeQuietly(serverPipeFd);
    }
  }
コード例 #2
0
  public void testLocalConnections() throws IOException {
    // create client and server socket
    LocalServerSocket localServerSocket = new LocalServerSocket(mSockAddr);
    LocalSocket clientSocket = new LocalSocket();

    // establish connection between client and server
    LocalSocketAddress locSockAddr = new LocalSocketAddress(mSockAddr);
    assertFalse(clientSocket.isConnected());
    clientSocket.connect(locSockAddr);
    assertTrue(clientSocket.isConnected());
    LocalSocket serverSocket = localServerSocket.accept();

    Credentials credent = clientSocket.getPeerCredentials();
    assertTrue(0 != credent.getPid());

    // send data from client to server
    OutputStream clientOutStream = clientSocket.getOutputStream();
    clientOutStream.write(12);
    InputStream serverInStream = serverSocket.getInputStream();
    assertEquals(12, serverInStream.read());

    // send data from server to client
    OutputStream serverOutStream = serverSocket.getOutputStream();
    serverOutStream.write(3);
    InputStream clientInStream = clientSocket.getInputStream();
    assertEquals(3, clientInStream.read());

    // Test sending and receiving file descriptors
    clientSocket.setFileDescriptorsForSend(new FileDescriptor[] {FileDescriptor.in});
    clientOutStream.write(32);
    assertEquals(32, serverInStream.read());

    FileDescriptor[] out = serverSocket.getAncillaryFileDescriptors();
    assertEquals(1, out.length);
    FileDescriptor fd = clientSocket.getFileDescriptor();
    assertTrue(fd.valid());

    // shutdown input stream of client
    clientSocket.shutdownInput();
    assertEquals(-1, clientInStream.read());

    // shutdown output stream of client
    clientSocket.shutdownOutput();
    try {
      clientOutStream.write(10);
      fail("testLocalSocket shouldn't come to here");
    } catch (IOException e) {
      // expected
    }

    // shutdown input stream of server
    serverSocket.shutdownInput();
    assertEquals(-1, serverInStream.read());

    // shutdown output stream of server
    serverSocket.shutdownOutput();
    try {
      serverOutStream.write(10);
      fail("testLocalSocket shouldn't come to here");
    } catch (IOException e) {
      // expected
    }

    // close client socket
    clientSocket.close();
    try {
      clientInStream.read();
      fail("testLocalSocket shouldn't come to here");
    } catch (IOException e) {
      // expected
    }

    // close server socket
    serverSocket.close();
    try {
      serverInStream.read();
      fail("testLocalSocket shouldn't come to here");
    } catch (IOException e) {
      // expected
    }
  }