Reading from logd in WRAP mode is expected to take a long time,
don't abort it after 30s.

Adds a new CTS test to verify the behaviour.

Bug: 64143705
Test: New and existing CTS tests pass. Manual testing with logcat.

(cherry picked from commit 64acdf77d6f89a72be9192b35e0fc34242c23e34)

Change-Id: Ic2ec131a3aee293ee865c46e62566ddd82ec2507
diff --git a/liblog/logd_reader.c b/liblog/logd_reader.c
index 600f4bb..603ba24 100644
--- a/liblog/logd_reader.c
+++ b/liblog/logd_reader.c
@@ -590,20 +590,30 @@
 
   memset(log_msg, 0, sizeof(*log_msg));
 
+  unsigned int new_alarm = 0;
   if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
+    if ((logger_list->mode & ANDROID_LOG_WRAP) &&
+        (logger_list->start.tv_sec || logger_list->start.tv_nsec)) {
+      /* b/64143705 */
+      new_alarm = (ANDROID_LOG_WRAP_DEFAULT_TIMEOUT * 11) / 10 + 10;
+      logger_list->mode &= ~ANDROID_LOG_WRAP;
+    } else {
+      new_alarm = 30;
+    }
+
     memset(&ignore, 0, sizeof(ignore));
     ignore.sa_handler = caught_signal;
     sigemptyset(&ignore.sa_mask);
     /* particularily useful if tombstone is reporting for logd */
     sigaction(SIGALRM, &ignore, &old_sigaction);
-    old_alarm = alarm(30);
+    old_alarm = alarm(new_alarm);
   }
 
   /* NOTE: SOCK_SEQPACKET guarantees we read exactly one full entry */
   ret = recv(ret, log_msg, LOGGER_ENTRY_MAX_LEN, 0);
   e = errno;
 
-  if (logger_list->mode & ANDROID_LOG_NONBLOCK) {
+  if (new_alarm) {
     if ((ret == 0) || (e == EINTR)) {
       e = EAGAIN;
       ret = -1;