Fix crash when socket read is interrupted

The exception is thrown in some normal cases e.g. interrupt()
called when Os.read is blocked and waiting for the input.
Ignore such events.

Test: 1. atest NetworkStackCoverageMtsConfigTests on S device
      2. atest com.android.cts.net.HostsideVpnTests
      3. atest NetworkStatsIntegrationTest
Bug: 259632210
Change-Id: Ibff41312d9c7431c2b19f780844ab3a81b48f9e8
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/NatPacketForwarderBase.java b/staticlibs/testutils/devicetests/com/android/testutils/NatPacketForwarderBase.java
index 85c6493..0a2b5d4 100644
--- a/staticlibs/testutils/devicetests/com/android/testutils/NatPacketForwarderBase.java
+++ b/staticlibs/testutils/devicetests/com/android/testutils/NatPacketForwarderBase.java
@@ -151,7 +151,8 @@
     private void processPacket() {
         final int len = PacketReflectorUtil.readPacket(mSrcFd, mBuf);
         if (len < 1) {
-            throw new IllegalStateException("Unexpected buffer length: " + len);
+            // Usually happens when socket read is being interrupted, e.g. stopping PacketForwarder.
+            return;
         }
 
         final int version = mBuf[0] >>> 4;
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/PacketReflectorUtil.kt b/staticlibs/testutils/devicetests/com/android/testutils/PacketReflectorUtil.kt
index b028045..498b1a3 100644
--- a/staticlibs/testutils/devicetests/com/android/testutils/PacketReflectorUtil.kt
+++ b/staticlibs/testutils/devicetests/com/android/testutils/PacketReflectorUtil.kt
@@ -20,11 +20,12 @@
 
 import android.system.ErrnoException
 import android.system.Os
+import android.system.OsConstants
 import com.android.net.module.util.IpUtils
 import com.android.testutils.PacketReflector.IPV4_HEADER_LENGTH
 import com.android.testutils.PacketReflector.IPV6_HEADER_LENGTH
 import java.io.FileDescriptor
-import java.io.IOException
+import java.io.InterruptedIOException
 import java.net.InetAddress
 import java.nio.ByteBuffer
 
@@ -32,8 +33,15 @@
     return try {
         Os.read(fd, buf, 0, buf.size)
     } catch (e: ErrnoException) {
-        -1
-    } catch (e: IOException) {
+        // Ignore normal use cases such as the EAGAIN error indicates that the read operation
+        // cannot be completed immediately, or the EINTR error indicates that the read
+        // operation was interrupted by a signal.
+        if (e.errno == OsConstants.EAGAIN || e.errno == OsConstants.EINTR) {
+            -1
+        } else {
+            throw e
+        }
+    } catch (e: InterruptedIOException) {
         -1
     }
 }