Merge changes Ibf4774f7,I6568eea0,I35e83679,I9faf8826,I8ee9d999
* changes:
fs_mgr: use __android_log_is_debuggable()
adb: use __android_log_is_debuggable()
debuggerd: use __android_log_is_debuggable()
logd: use __android_log_is_debuggable()
libcutils: use __android_log_is_debuggable()
diff --git a/Android.bp b/Android.bp
deleted file mode 100644
index 949a7fe..0000000
--- a/Android.bp
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (C) 2016 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-ndk_headers {
- name: "liblog_headers",
- from: "include/android",
- to: "android",
- srcs: ["include/android/log.h"],
-}
-
-optional_subdirs = ["*"]
diff --git a/include/cutils/sockets.h b/include/cutils/sockets.h
index b9c22c1..4626e7a 100644
--- a/include/cutils/sockets.h
+++ b/include/cutils/sockets.h
@@ -84,7 +84,6 @@
*
* These functions return INVALID_SOCKET (-1) on failure for all platforms.
*/
-int socket_loopback_client(int port, int type);
cutils_socket_t socket_network_client(const char* host, int port, int type);
int socket_network_client_timeout(const char* host, int port, int type,
int timeout, int* getaddrinfo_error);
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index 94275bd..943926b 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -23,7 +23,6 @@
"socket_inaddr_any_server_unix.c",
"socket_local_client_unix.c",
"socket_local_server_unix.c",
- "socket_loopback_client_unix.c",
"socket_loopback_server_unix.c",
"socket_network_client_unix.c",
"sockets_unix.cpp",
diff --git a/libcutils/socket_loopback_client_unix.c b/libcutils/socket_loopback_client_unix.c
deleted file mode 100644
index 137e369..0000000
--- a/libcutils/socket_loopback_client_unix.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#if !defined(_WIN32)
-#include <sys/socket.h>
-#include <sys/select.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#endif
-
-#include <cutils/sockets.h>
-
-/* Connect to port on the loopback IP interface. type is
- * SOCK_STREAM or SOCK_DGRAM.
- * return is a file descriptor or -1 on error
- */
-int socket_loopback_client(int port, int type)
-{
- return socket_network_client("localhost", port, type);
-}
-
diff --git a/liblog/Android.bp b/liblog/Android.bp
index c59dde9..bbaced5 100644
--- a/liblog/Android.bp
+++ b/liblog/Android.bp
@@ -91,6 +91,21 @@
compile_multilib: "both",
}
+// system/core/android/log.h needs some work before it can be included in the
+// NDK. It defines a *lot* of macros that previously were usable names in NDK
+// sources that used android/log.h. As an example, the following file defines
+// LOG_TAG as a variable, but the variable name gets macro replaced if we use
+// the current android/log.h.
+// https://android.googlesource.com/platform/external/deqp/+/4adc1515f867b26c19c2f7498e9de93a230a234d/framework/platform/android/tcuTestLogParserJNI.cpp#41
+//
+// For now, we keep a copy of the old NDK android/log.h in legacy-ndk-includes.
+ndk_headers {
+ name: "liblog_headers",
+ from: "legacy-ndk-includes",
+ to: "android",
+ srcs: ["legacy-ndk-includes/log.h"],
+}
+
ndk_library {
name: "liblog.ndk",
symbol_file: "liblog.map.txt",
diff --git a/liblog/legacy-ndk-includes/log.h b/liblog/legacy-ndk-includes/log.h
new file mode 100644
index 0000000..0ea4c29
--- /dev/null
+++ b/liblog/legacy-ndk-includes/log.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ANDROID_LOG_H
+#define _ANDROID_LOG_H
+
+/******************************************************************
+ *
+ * IMPORTANT NOTICE:
+ *
+ * This file is part of Android's set of stable system headers
+ * exposed by the Android NDK (Native Development Kit) since
+ * platform release 1.5
+ *
+ * Third-party source AND binary code relies on the definitions
+ * here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.
+ *
+ * - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)
+ * - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS
+ * - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY
+ * - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
+ */
+
+/*
+ * Support routines to send messages to the Android in-kernel log buffer,
+ * which can later be accessed through the 'logcat' utility.
+ *
+ * Each log message must have
+ * - a priority
+ * - a log tag
+ * - some text
+ *
+ * The tag normally corresponds to the component that emits the log message,
+ * and should be reasonably small.
+ *
+ * Log message text may be truncated to less than an implementation-specific
+ * limit (e.g. 1023 characters max).
+ *
+ * Note that a newline character ("\n") will be appended automatically to your
+ * log message, if not already there. It is not possible to send several messages
+ * and have them appear on a single line in logcat.
+ *
+ * PLEASE USE LOGS WITH MODERATION:
+ *
+ * - Sending log messages eats CPU and slow down your application and the
+ * system.
+ *
+ * - The circular log buffer is pretty small (<64KB), sending many messages
+ * might push off other important log messages from the rest of the system.
+ *
+ * - In release builds, only send log messages to account for exceptional
+ * conditions.
+ *
+ * NOTE: These functions MUST be implemented by /system/lib/liblog.so
+ */
+
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Android log priority values, in ascending priority order.
+ */
+typedef enum android_LogPriority {
+ ANDROID_LOG_UNKNOWN = 0,
+ ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */
+ ANDROID_LOG_VERBOSE,
+ ANDROID_LOG_DEBUG,
+ ANDROID_LOG_INFO,
+ ANDROID_LOG_WARN,
+ ANDROID_LOG_ERROR,
+ ANDROID_LOG_FATAL,
+ ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */
+} android_LogPriority;
+
+/*
+ * Send a simple string to the log.
+ */
+int __android_log_write(int prio, const char *tag, const char *text);
+
+/*
+ * Send a formatted string to the log, used like printf(fmt,...)
+ */
+int __android_log_print(int prio, const char *tag, const char *fmt, ...)
+#if defined(__GNUC__)
+ __attribute__ ((format(printf, 3, 4)))
+#endif
+ ;
+
+/*
+ * A variant of __android_log_print() that takes a va_list to list
+ * additional parameters.
+ */
+int __android_log_vprint(int prio, const char *tag,
+ const char *fmt, va_list ap);
+
+/*
+ * Log an assertion failure and SIGTRAP the process to have a chance
+ * to inspect it, if a debugger is attached. This uses the FATAL priority.
+ */
+void __android_log_assert(const char *cond, const char *tag,
+ const char *fmt, ...)
+#if defined(__GNUC__)
+ __attribute__ ((noreturn))
+ __attribute__ ((format(printf, 3, 4)))
+#endif
+ ;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ANDROID_LOG_H */
diff --git a/liblog/logd_reader.c b/liblog/logd_reader.c
index 563b5c7..71ff075 100644
--- a/liblog/logd_reader.c
+++ b/liblog/logd_reader.c
@@ -482,17 +482,17 @@
struct sigaction old_sigaction;
unsigned int old_alarm = 0;
char buffer[256], *cp, c;
- int e, ret, remaining;
-
- int sock = transp->context.sock;
- if (sock > 0) {
- return sock;
- }
+ int e, ret, remaining, sock;
if (!logger_list) {
return -EINVAL;
}
+ sock = atomic_load(&transp->context.sock);
+ if (sock > 0) {
+ return sock;
+ }
+
sock = socket_local_client("logdr",
ANDROID_SOCKET_NAMESPACE_RESERVED,
SOCK_SEQPACKET);
@@ -587,7 +587,11 @@
return ret;
}
- return transp->context.sock = sock;
+ ret = atomic_exchange(&transp->context.sock, sock);
+ if ((ret > 0) && (ret != sock)) {
+ close(ret);
+ }
+ return sock;
}
/* Read from the selected logs */
@@ -662,8 +666,8 @@
static void logdClose(struct android_log_logger_list *logger_list __unused,
struct android_log_transport_context *transp)
{
- if (transp->context.sock > 0) {
- close (transp->context.sock);
- transp->context.sock = -1;
+ int sock = atomic_exchange(&transp->context.sock, -1);
+ if (sock > 0) {
+ close (sock);
}
}
diff --git a/liblog/logd_writer.c b/liblog/logd_writer.c
index e8e392d..2913507 100644
--- a/liblog/logd_writer.c
+++ b/liblog/logd_writer.c
@@ -31,7 +31,6 @@
#include <time.h>
#include <unistd.h>
-#include <android/log.h>
#include <cutils/sockets.h>
#include <log/logger.h>
#include <private/android_filesystem_config.h>
@@ -65,7 +64,8 @@
{
int i, ret = 0;
- if (logdLoggerWrite.context.sock < 0) {
+ i = atomic_load(&logdLoggerWrite.context.sock);
+ if (i < 0) {
i = TEMP_FAILURE_RETRY(socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0));
if (i < 0) {
ret = -errno;
@@ -80,7 +80,11 @@
ret = -errno;
close(i);
} else {
- logdLoggerWrite.context.sock = i;
+ ret = atomic_exchange(&logdLoggerWrite.context.sock, i);
+ if ((ret >= 0) && (ret != i)) {
+ close(ret);
+ }
+ ret = 0;
}
}
}
@@ -90,9 +94,9 @@
static void logdClose()
{
- if (logdLoggerWrite.context.sock >= 0) {
- close(logdLoggerWrite.context.sock);
- logdLoggerWrite.context.sock = -1;
+ int sock = atomic_exchange(&logdLoggerWrite.context.sock, -1);
+ if (sock >= 0) {
+ close(sock);
}
}
@@ -101,7 +105,7 @@
if (logId > LOG_ID_SECURITY) {
return -EINVAL;
}
- if (logdLoggerWrite.context.sock < 0) {
+ if (atomic_load(&logdLoggerWrite.context.sock) < 0) {
if (access("/dev/socket/logdw", W_OK) == 0) {
return 0;
}
@@ -121,7 +125,7 @@
static atomic_int_fast32_t dropped;
static atomic_int_fast32_t droppedSecurity;
- if (logdLoggerWrite.context.sock < 0) {
+ if (atomic_load(&logdLoggerWrite.context.sock) < 0) {
return -EBADF;
}
@@ -160,7 +164,7 @@
newVec[0].iov_base = (unsigned char *)&header;
newVec[0].iov_len = sizeof(header);
- if (logdLoggerWrite.context.sock > 0) {
+ if (atomic_load(&logdLoggerWrite.context.sock) > 0) {
int32_t snapshot = atomic_exchange_explicit(&droppedSecurity, 0,
memory_order_relaxed);
if (snapshot) {
@@ -174,7 +178,8 @@
newVec[headerLength].iov_base = &buffer;
newVec[headerLength].iov_len = sizeof(buffer);
- ret = TEMP_FAILURE_RETRY(writev(logdLoggerWrite.context.sock, newVec, 2));
+ ret = TEMP_FAILURE_RETRY(writev(
+ atomic_load(&logdLoggerWrite.context.sock), newVec, 2));
if (ret != (ssize_t)(sizeof(header) + sizeof(buffer))) {
atomic_fetch_add_explicit(&droppedSecurity, snapshot,
memory_order_relaxed);
@@ -194,7 +199,8 @@
newVec[headerLength].iov_base = &buffer;
newVec[headerLength].iov_len = sizeof(buffer);
- ret = TEMP_FAILURE_RETRY(writev(logdLoggerWrite.context.sock, newVec, 2));
+ ret = TEMP_FAILURE_RETRY(writev(
+ atomic_load(&logdLoggerWrite.context.sock), newVec, 2));
if (ret != (ssize_t)(sizeof(header) + sizeof(buffer))) {
atomic_fetch_add_explicit(&dropped, snapshot,
memory_order_relaxed);
@@ -223,7 +229,8 @@
* ENOTCONN occurs if logd dies.
* EAGAIN occurs if logd is overloaded.
*/
- ret = TEMP_FAILURE_RETRY(writev(logdLoggerWrite.context.sock, newVec, i));
+ ret = TEMP_FAILURE_RETRY(writev(
+ atomic_load(&logdLoggerWrite.context.sock), newVec, i));
if (ret < 0) {
ret = -errno;
if (ret == -ENOTCONN) {
@@ -236,7 +243,8 @@
return ret;
}
- ret = TEMP_FAILURE_RETRY(writev(logdLoggerWrite.context.sock, newVec, i));
+ ret = TEMP_FAILURE_RETRY(writev(
+ atomic_load(&logdLoggerWrite.context.sock), newVec, i));
if (ret < 0) {
ret = -errno;
}
diff --git a/liblog/logger.h b/liblog/logger.h
index bacb243..d2aebcb 100644
--- a/liblog/logger.h
+++ b/liblog/logger.h
@@ -17,6 +17,7 @@
#ifndef _LIBLOG_LOGGER_H__
#define _LIBLOG_LOGGER_H__
+#include <stdatomic.h>
#include <stdbool.h>
#include <log/uio.h>
@@ -31,9 +32,10 @@
/* Union, sock or fd of zero is not allowed unless static initialized */
union android_log_context {
void *private;
- int sock;
- int fd;
+ atomic_int sock;
+ atomic_int fd;
struct listnode *node;
+ atomic_uintptr_t atomic_pointer;
};
struct android_log_transport_write {
diff --git a/liblog/pmsg_reader.c b/liblog/pmsg_reader.c
index 679c159..a0a69c1 100644
--- a/liblog/pmsg_reader.c
+++ b/liblog/pmsg_reader.c
@@ -151,8 +151,8 @@
memset(log_msg, 0, sizeof(*log_msg));
- if (transp->context.fd <= 0) {
- int fd = open("/sys/fs/pstore/pmsg-ramoops-0", O_RDONLY | O_CLOEXEC);
+ if (atomic_load(&transp->context.fd) <= 0) {
+ int i, fd = open("/sys/fs/pstore/pmsg-ramoops-0", O_RDONLY | O_CLOEXEC);
if (fd < 0) {
return -errno;
@@ -164,13 +164,22 @@
return -errno;
}
}
- transp->context.fd = fd;
+ i = atomic_exchange(&transp->context.fd, fd);
+ if ((i > 0) && (i != fd)) {
+ close(i);
+ }
preread_count = 0;
}
while(1) {
+ int fd;
+
if (preread_count < sizeof(buf)) {
- ret = TEMP_FAILURE_RETRY(read(transp->context.fd,
+ fd = atomic_load(&transp->context.fd);
+ if (fd <= 0) {
+ return -EBADF;
+ }
+ ret = TEMP_FAILURE_RETRY(read(fd,
&buf.p.magic + preread_count,
sizeof(buf) - preread_count));
if (ret < 0) {
@@ -212,9 +221,13 @@
log_msg->entry_v4.msg :
log_msg->entry_v3.msg;
*msg = buf.prio;
- ret = TEMP_FAILURE_RETRY(read(transp->context.fd,
- msg + sizeof(buf.prio),
- buf.p.len - sizeof(buf)));
+ fd = atomic_load(&transp->context.fd);
+ if (fd <= 0) {
+ return -EBADF;
+ }
+ ret = TEMP_FAILURE_RETRY(read(fd,
+ msg + sizeof(buf.prio),
+ buf.p.len - sizeof(buf)));
if (ret < 0) {
return -errno;
}
@@ -239,12 +252,19 @@
}
}
- current = TEMP_FAILURE_RETRY(lseek(transp->context.fd,
- (off_t)0, SEEK_CUR));
+ fd = atomic_load(&transp->context.fd);
+ if (fd <= 0) {
+ return -EBADF;
+ }
+ current = TEMP_FAILURE_RETRY(lseek(fd, (off_t)0, SEEK_CUR));
if (current < 0) {
return -errno;
}
- next = TEMP_FAILURE_RETRY(lseek(transp->context.fd,
+ fd = atomic_load(&transp->context.fd);
+ if (fd <= 0) {
+ return -EBADF;
+ }
+ next = TEMP_FAILURE_RETRY(lseek(fd,
(off_t)(buf.p.len - sizeof(buf)),
SEEK_CUR));
if (next < 0) {
@@ -258,10 +278,10 @@
static void pmsgClose(struct android_log_logger_list *logger_list __unused,
struct android_log_transport_context *transp) {
- if (transp->context.fd > 0) {
- close (transp->context.fd);
+ int fd = atomic_exchange(&transp->context.fd, 0);
+ if (fd > 0) {
+ close (fd);
}
- transp->context.fd = 0;
}
LIBLOG_ABI_PRIVATE ssize_t __android_log_pmsg_file_read(
diff --git a/liblog/pmsg_writer.c b/liblog/pmsg_writer.c
index 06652f3..b3c4a1a 100644
--- a/liblog/pmsg_writer.c
+++ b/liblog/pmsg_writer.c
@@ -20,6 +20,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
@@ -53,18 +54,25 @@
static int pmsgOpen()
{
- if (pmsgLoggerWrite.context.fd < 0) {
- pmsgLoggerWrite.context.fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
+ int fd = atomic_load(&pmsgLoggerWrite.context.fd);
+ if (fd < 0) {
+ int i;
+
+ fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
+ i = atomic_exchange(&pmsgLoggerWrite.context.fd, fd);
+ if ((i >= 0) && (i != fd)) {
+ close(i);
+ }
}
- return pmsgLoggerWrite.context.fd;
+ return fd;
}
static void pmsgClose()
{
- if (pmsgLoggerWrite.context.fd >= 0) {
- close(pmsgLoggerWrite.context.fd);
- pmsgLoggerWrite.context.fd = -1;
+ int fd = atomic_exchange(&pmsgLoggerWrite.context.fd, -1);
+ if (fd >= 0) {
+ close(fd);
}
}
@@ -78,7 +86,7 @@
!__android_log_is_debuggable()) {
return -EINVAL;
}
- if (pmsgLoggerWrite.context.fd < 0) {
+ if (atomic_load(&pmsgLoggerWrite.context.fd) < 0) {
if (access("/dev/pmsg0", W_OK) == 0) {
return 0;
}
@@ -115,7 +123,7 @@
}
}
- if (pmsgLoggerWrite.context.fd < 0) {
+ if (atomic_load(&pmsgLoggerWrite.context.fd) < 0) {
return -EBADF;
}
@@ -169,7 +177,8 @@
}
pmsgHeader.len += payloadSize;
- ret = TEMP_FAILURE_RETRY(writev(pmsgLoggerWrite.context.fd, newVec, i));
+ ret = TEMP_FAILURE_RETRY(writev(atomic_load(&pmsgLoggerWrite.context.fd),
+ newVec, i));
if (ret < 0) {
ret = errno ? -errno : -ENOTCONN;
}
@@ -206,7 +215,7 @@
char prio,
const char *filename,
const char *buf, size_t len) {
- int fd;
+ bool weOpened;
size_t length, packet_len;
const char *tag;
char *cp, *slash;
@@ -228,16 +237,6 @@
return -ENOMEM;
}
- fd = pmsgLoggerWrite.context.fd;
- if (fd < 0) {
- __android_log_lock();
- fd = pmsgOpen();
- __android_log_unlock();
- if (fd < 0) {
- return -EBADF;
- }
- }
-
tag = cp;
slash = strrchr(cp, '/');
if (slash) {
@@ -256,6 +255,7 @@
vec[1].iov_base = (unsigned char *)tag;
vec[1].iov_len = length;
+ weOpened = false;
for (ts.tv_nsec = 0, length = len;
length;
ts.tv_nsec += ANDROID_LOG_PMSG_FILE_SEQUENCE) {
@@ -279,15 +279,36 @@
vec[2].iov_base = (unsigned char *)buf;
vec[2].iov_len = transfer;
+ if (atomic_load(&pmsgLoggerWrite.context.fd) < 0) {
+ if (!weOpened) { /* Impossible for weOpened = true here */
+ __android_log_lock();
+ }
+ weOpened = atomic_load(&pmsgLoggerWrite.context.fd) < 0;
+ if (!weOpened) {
+ __android_log_unlock();
+ } else if (pmsgOpen() < 0) {
+ __android_log_unlock();
+ return -EBADF;
+ }
+ }
+
ret = pmsgWrite(logId, &ts, vec, sizeof(vec) / sizeof(vec[0]));
if (ret <= 0) {
+ if (weOpened) {
+ pmsgClose();
+ __android_log_unlock();
+ }
free(cp);
- return ret;
+ return ret ? ret : (len - length);
}
length -= transfer;
buf += transfer;
}
+ if (weOpened) {
+ pmsgClose();
+ __android_log_unlock();
+ }
free(cp);
return len;
}
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index b1dae9e..7db048d 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -20,6 +20,7 @@
#include <inttypes.h>
#include <semaphore.h>
#include <signal.h>
+#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
@@ -129,6 +130,70 @@
ASSERT_LT(0, ret);
}
+std::string popenToString(std::string command) {
+ std::string ret;
+
+ FILE* fp = popen(command.c_str(), "r");
+ if (fp) {
+ if (!android::base::ReadFdToString(fileno(fp), &ret)) ret = "";
+ pclose(fp);
+ }
+ return ret;
+}
+
+static bool isPmsgActive() {
+ pid_t pid = getpid();
+
+ std::string myPidFds = popenToString(android::base::StringPrintf(
+ "ls -l /proc/%d/fd", pid));
+ if (myPidFds.length() == 0) return true; // guess it is?
+
+ return std::string::npos != myPidFds.find(" -> /dev/pmsg0");
+}
+
+static bool isLogdwActive() {
+ std::string logdwSignature = popenToString(
+ "grep /dev/socket/logdw /proc/net/unix");
+ size_t beginning = logdwSignature.find(" ");
+ if (beginning == std::string::npos) return true;
+ beginning = logdwSignature.find(" ", beginning + 1);
+ if (beginning == std::string::npos) return true;
+ size_t end = logdwSignature.find(" ", beginning + 1);
+ if (end == std::string::npos) return true;
+ end = logdwSignature.find(" ", end + 1);
+ if (end == std::string::npos) return true;
+ end = logdwSignature.find(" ", end + 1);
+ if (end == std::string::npos) return true;
+ end = logdwSignature.find(" ", end + 1);
+ if (end == std::string::npos) return true;
+ std::string allLogdwEndpoints = popenToString(
+ "grep ' 00000002" +
+ logdwSignature.substr(beginning, end - beginning) +
+ " ' /proc/net/unix | " +
+ "sed -n 's/.* \\([0-9][0-9]*\\)$/ -> socket:[\\1]/p'");
+ if (allLogdwEndpoints.length() == 0) return true;
+
+ // NB: allLogdwEndpoints has some false positives in it, but those
+ // strangers do not overlap with the simplistic activities inside this
+ // test suite.
+
+ pid_t pid = getpid();
+
+ std::string myPidFds = popenToString(android::base::StringPrintf(
+ "ls -l /proc/%d/fd", pid));
+ if (myPidFds.length() == 0) return true;
+
+ // NB: fgrep with multiple strings is broken in Android
+ for (beginning = 0;
+ (end = allLogdwEndpoints.find("\n", beginning)) != std::string::npos;
+ beginning = end + 1) {
+ if (myPidFds.find(allLogdwEndpoints.substr(beginning,
+ end - beginning)) !=
+ std::string::npos) return true;
+ }
+ return false;
+}
+
TEST(liblog, __android_log_btwrite__android_logger_list_read) {
struct logger_list *logger_list;
@@ -140,10 +205,22 @@
// Check that we can close and reopen the logger
log_time ts(CLOCK_MONOTONIC);
ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
+ bool pmsgActiveAfter__android_log_btwrite = isPmsgActive();
+ bool logdwActiveAfter__android_log_btwrite = isLogdwActive();
+ EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite);
+ EXPECT_TRUE(logdwActiveAfter__android_log_btwrite);
__android_log_close();
+ bool pmsgActiveAfter__android_log_close = isPmsgActive();
+ bool logdwActiveAfter__android_log_close = isLogdwActive();
+ EXPECT_FALSE(pmsgActiveAfter__android_log_close);
+ EXPECT_FALSE(logdwActiveAfter__android_log_close);
log_time ts1(CLOCK_MONOTONIC);
ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1)));
+ pmsgActiveAfter__android_log_btwrite = isPmsgActive();
+ logdwActiveAfter__android_log_btwrite = isLogdwActive();
+ EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite);
+ EXPECT_TRUE(logdwActiveAfter__android_log_btwrite);
usleep(1000000);
int count = 0;
@@ -2575,12 +2652,35 @@
"/data/william-shakespeare/MuchAdoAboutNothing.txt";
TEST(liblog, __android_log_pmsg_file_write) {
+ __android_log_close();
+ bool pmsgActiveAfter__android_log_close = isPmsgActive();
+ bool logdwActiveAfter__android_log_close = isLogdwActive();
+ EXPECT_FALSE(pmsgActiveAfter__android_log_close);
+ EXPECT_FALSE(logdwActiveAfter__android_log_close);
EXPECT_LT(0, __android_log_pmsg_file_write(
LOG_ID_CRASH, ANDROID_LOG_VERBOSE,
__pmsg_file, max_payload_buf, sizeof(max_payload_buf)));
fprintf(stderr, "Reboot, ensure file %s matches\n"
"with liblog.__android_log_msg_file_read test\n",
__pmsg_file);
+ bool pmsgActiveAfter__android_pmsg_file_write = isPmsgActive();
+ bool logdwActiveAfter__android_pmsg_file_write = isLogdwActive();
+ EXPECT_FALSE(pmsgActiveAfter__android_pmsg_file_write);
+ EXPECT_FALSE(logdwActiveAfter__android_pmsg_file_write);
+ EXPECT_LT(0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,
+ "TEST__android_log_pmsg_file_write",
+ "main"));
+ bool pmsgActiveAfter__android_log_buf_print = isPmsgActive();
+ bool logdwActiveAfter__android_log_buf_print = isLogdwActive();
+ EXPECT_TRUE(pmsgActiveAfter__android_log_buf_print);
+ EXPECT_TRUE(logdwActiveAfter__android_log_buf_print);
+ EXPECT_LT(0, __android_log_pmsg_file_write(
+ LOG_ID_CRASH, ANDROID_LOG_VERBOSE,
+ __pmsg_file, max_payload_buf, sizeof(max_payload_buf)));
+ pmsgActiveAfter__android_pmsg_file_write = isPmsgActive();
+ logdwActiveAfter__android_pmsg_file_write = isLogdwActive();
+ EXPECT_TRUE(pmsgActiveAfter__android_pmsg_file_write);
+ EXPECT_TRUE(logdwActiveAfter__android_pmsg_file_write);
}
ssize_t __pmsg_fn(log_id_t logId, char prio, const char *filename,
@@ -2597,7 +2697,7 @@
strcmp(max_payload_buf, buf)) {
fprintf(stderr, "comparison fails on content \"%s\"\n", buf);
}
- return !arg ||
+ return arg ||
(LOG_ID_CRASH != logId) ||
(ANDROID_LOG_VERBOSE != prio) ||
!strstr(__pmsg_file, filename) ||
@@ -2608,10 +2708,21 @@
TEST(liblog, __android_log_pmsg_file_read) {
signaled = 0;
+ __android_log_close();
+ bool pmsgActiveAfter__android_log_close = isPmsgActive();
+ bool logdwActiveAfter__android_log_close = isLogdwActive();
+ EXPECT_FALSE(pmsgActiveAfter__android_log_close);
+ EXPECT_FALSE(logdwActiveAfter__android_log_close);
+
ssize_t ret = __android_log_pmsg_file_read(
LOG_ID_CRASH, ANDROID_LOG_VERBOSE,
__pmsg_file, __pmsg_fn, NULL);
+ bool pmsgActiveAfter__android_log_pmsg_file_read = isPmsgActive();
+ bool logdwActiveAfter__android_log_pmsg_file_read = isLogdwActive();
+ EXPECT_FALSE(pmsgActiveAfter__android_log_pmsg_file_read);
+ EXPECT_FALSE(logdwActiveAfter__android_log_pmsg_file_read);
+
if (ret == -ENOENT) {
fprintf(stderr,
"No pre-boot results of liblog.__android_log_mesg_file_write to "