Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c29a8f6e authored by Hans Boehm's avatar Hans Boehm
Browse files

Clear buffer on reconnect & check poll() result

Clear the buffer again whenever we have to reconnect. It's unclear
this matters in normal operation, but this precludes some failure
modes.

Check poll() for an error return like ENOMEM.

Bug: 315482121
Test: Treehugger
Change-Id: I67fb6d73bde6a8f54ce297e5269641abea48b9b0
parent 2f005a18
Loading
Loading
Loading
Loading
+9 −5
Original line number Original line Diff line number Diff line
@@ -63,6 +63,7 @@ class NativeCommandBuffer {
  std::optional<std::pair<char*, char*>> readLine(FailFn fail_fn) {
  std::optional<std::pair<char*, char*>> readLine(FailFn fail_fn) {
    char* result = mBuffer + mNext;
    char* result = mBuffer + mNext;
    while (true) {
    while (true) {
      // We have scanned up to, but not including mNext for this line's newline.
      if (mNext == mEnd) {
      if (mNext == mEnd) {
        if (mEnd == MAX_COMMAND_BYTES) {
        if (mEnd == MAX_COMMAND_BYTES) {
          return {};
          return {};
@@ -89,7 +90,7 @@ class NativeCommandBuffer {
      } else {
      } else {
        mNext = nl - mBuffer + 1;
        mNext = nl - mBuffer + 1;
        if (--mLinesLeft < 0) {
        if (--mLinesLeft < 0) {
          fail_fn("ZygoteCommandBuffer.readLine attempted to read past mEnd of command");
          fail_fn("ZygoteCommandBuffer.readLine attempted to read past end of command");
        }
        }
        return std::make_pair(result, nl);
        return std::make_pair(result, nl);
      }
      }
@@ -125,8 +126,8 @@ class NativeCommandBuffer {
    mEnd += lineLen + 1;
    mEnd += lineLen + 1;
  }
  }


  // Clear mBuffer, start reading new command, return the number of arguments, leaving mBuffer
  // Start reading new command, return the number of arguments, leaving mBuffer positioned at the
  // positioned at the beginning of first argument. Return 0 on EOF.
  // beginning of first argument. Return 0 on EOF.
  template<class FailFn>
  template<class FailFn>
  int getCount(FailFn fail_fn) {
  int getCount(FailFn fail_fn) {
    mLinesLeft = 1;
    mLinesLeft = 1;
@@ -451,11 +452,14 @@ jboolean com_android_internal_os_ZygoteCommandBuffer_nativeForkRepeatedly(
            (CREATE_ERROR("Write unexpectedly returned short: %d < 5", res));
            (CREATE_ERROR("Write unexpectedly returned short: %d < 5", res));
      }
      }
    }
    }
    for (;;) {
      // Clear buffer and get count from next command.
      // Clear buffer and get count from next command.
      n_buffer->clear();
      n_buffer->clear();
    for (;;) {
      // Poll isn't strictly necessary for now. But without it, disconnect is hard to detect.
      // Poll isn't strictly necessary for now. But without it, disconnect is hard to detect.
      int poll_res = TEMP_FAILURE_RETRY(poll(fd_structs, 2, -1 /* infinite timeout */));
      int poll_res = TEMP_FAILURE_RETRY(poll(fd_structs, 2, -1 /* infinite timeout */));
      if (poll_res < 0) {
        fail_fn_z(CREATE_ERROR("Poll failed: %d: %s", errno, strerror(errno)));
      }
      if ((fd_structs[SESSION_IDX].revents & POLLIN) != 0) {
      if ((fd_structs[SESSION_IDX].revents & POLLIN) != 0) {
        if (n_buffer->getCount(fail_fn_z) != 0) {
        if (n_buffer->getCount(fail_fn_z) != 0) {
          break;
          break;