logd: fix write errors in no_epipe test am: 2e96097ff0 am: dcebdd3bc7
Original change: https://googleplex-android-review.googlesource.com/c/platform/system/logging/+/15523898
Change-Id: Ib3a87399146160c40b8fae7a5bdae12ef06622ce
diff --git a/liblog/logger_write.cpp b/liblog/logger_write.cpp
index 8793e82..08ab6e2 100644
--- a/liblog/logger_write.cpp
+++ b/liblog/logger_write.cpp
@@ -108,11 +108,10 @@
#endif
}
-#if defined(__GLIBC__) || defined(_WIN32)
+// BSD-based systems like Android/macOS have getprogname(). Others need us to provide one.
+#if !defined(__APPLE__) && !defined(__BIONIC__)
static const char* getprogname() {
-#if defined(__GLIBC__)
- return program_invocation_short_name;
-#elif defined(_WIN32)
+#ifdef _WIN32
static bool first = true;
static char progname[MAX_PATH] = {};
@@ -129,6 +128,8 @@
}
return progname;
+#else
+ return program_invocation_short_name;
#endif
}
#endif
@@ -267,7 +268,7 @@
log_message->tag ? log_message->tag : "nullptr", priority_char, timestamp, getpid(),
tid, log_message->file, log_message->line, log_message->message);
} else {
- fprintf(stderr, "%s %c %s %5d %5" PRIu64 " %s\n",
+ fprintf(stderr, "%s %c %s %5d %5" PRIu64 "] %s\n",
log_message->tag ? log_message->tag : "nullptr", priority_char, timestamp, getpid(),
tid, log_message->message);
}
diff --git a/liblog/logprint.cpp b/liblog/logprint.cpp
index a5c5edd..639b8d9 100644
--- a/liblog/logprint.cpp
+++ b/liblog/logprint.cpp
@@ -15,10 +15,6 @@
** limitations under the License.
*/
-#ifndef __MINGW32__
-#define HAVE_STRSEP
-#endif
-
#include <log/logprint.h>
#include <assert.h>
@@ -38,6 +34,8 @@
#include <cutils/list.h>
+#include <algorithm>
+
#include <log/log.h>
#include <log/log_read.h>
#include <private/android_logger.h>
@@ -45,10 +43,6 @@
#define MS_PER_NSEC 1000000
#define US_PER_NSEC 1000
-#ifndef MIN
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#endif
-
typedef struct FilterInfo_t {
char* mTag;
android_LogPriority mPri;
@@ -292,72 +286,71 @@
return 1;
}
-#ifndef __MINGW32__
-static const char tz[] = "TZ";
-static const char utc[] = "UTC";
+#if !defined(__MINGW32__)
+// Sets $TZ, but allows it to be optionally reset.
+class TzSetter {
+ public:
+ TzSetter(const char* new_tz) {
+ old_tz_ = getenv("TZ");
+ if (old_tz_) old_tz_ = strdup(old_tz_);
+
+ setenv("TZ", new_tz, 1);
+ tzset();
+ }
+
+ ~TzSetter() { free(old_tz_); }
+
+ void Reset() {
+ if (old_tz_) {
+ setenv("TZ", old_tz_, 1);
+ } else {
+ unsetenv("TZ");
+ }
+ tzset();
+ }
+
+ private:
+ char* old_tz_;
+};
#endif
-/**
- * Returns FORMAT_OFF on invalid string
- */
AndroidLogPrintFormat android_log_formatFromString(const char* formatString) {
- static AndroidLogPrintFormat format;
-
/* clang-format off */
- if (!strcmp(formatString, "brief")) format = FORMAT_BRIEF;
- else if (!strcmp(formatString, "process")) format = FORMAT_PROCESS;
- else if (!strcmp(formatString, "tag")) format = FORMAT_TAG;
- else if (!strcmp(formatString, "thread")) format = FORMAT_THREAD;
- else if (!strcmp(formatString, "raw")) format = FORMAT_RAW;
- else if (!strcmp(formatString, "time")) format = FORMAT_TIME;
- else if (!strcmp(formatString, "threadtime")) format = FORMAT_THREADTIME;
- else if (!strcmp(formatString, "long")) format = FORMAT_LONG;
- else if (!strcmp(formatString, "color")) format = FORMAT_MODIFIER_COLOR;
- else if (!strcmp(formatString, "colour")) format = FORMAT_MODIFIER_COLOR;
- else if (!strcmp(formatString, "usec")) format = FORMAT_MODIFIER_TIME_USEC;
- else if (!strcmp(formatString, "nsec")) format = FORMAT_MODIFIER_TIME_NSEC;
- else if (!strcmp(formatString, "printable")) format = FORMAT_MODIFIER_PRINTABLE;
- else if (!strcmp(formatString, "year")) format = FORMAT_MODIFIER_YEAR;
- else if (!strcmp(formatString, "zone")) format = FORMAT_MODIFIER_ZONE;
- else if (!strcmp(formatString, "epoch")) format = FORMAT_MODIFIER_EPOCH;
- else if (!strcmp(formatString, "monotonic")) format = FORMAT_MODIFIER_MONOTONIC;
- else if (!strcmp(formatString, "uid")) format = FORMAT_MODIFIER_UID;
- else if (!strcmp(formatString, "descriptive")) format = FORMAT_MODIFIER_DESCRIPT;
+ if (!strcmp(formatString, "brief")) return FORMAT_BRIEF;
+ if (!strcmp(formatString, "process")) return FORMAT_PROCESS;
+ if (!strcmp(formatString, "tag")) return FORMAT_TAG;
+ if (!strcmp(formatString, "thread")) return FORMAT_THREAD;
+ if (!strcmp(formatString, "raw")) return FORMAT_RAW;
+ if (!strcmp(formatString, "time")) return FORMAT_TIME;
+ if (!strcmp(formatString, "threadtime")) return FORMAT_THREADTIME;
+ if (!strcmp(formatString, "long")) return FORMAT_LONG;
+ if (!strcmp(formatString, "color")) return FORMAT_MODIFIER_COLOR;
+ if (!strcmp(formatString, "colour")) return FORMAT_MODIFIER_COLOR;
+ if (!strcmp(formatString, "usec")) return FORMAT_MODIFIER_TIME_USEC;
+ if (!strcmp(formatString, "nsec")) return FORMAT_MODIFIER_TIME_NSEC;
+ if (!strcmp(formatString, "printable")) return FORMAT_MODIFIER_PRINTABLE;
+ if (!strcmp(formatString, "year")) return FORMAT_MODIFIER_YEAR;
+ if (!strcmp(formatString, "zone")) return FORMAT_MODIFIER_ZONE;
+ if (!strcmp(formatString, "epoch")) return FORMAT_MODIFIER_EPOCH;
+ if (!strcmp(formatString, "monotonic")) return FORMAT_MODIFIER_MONOTONIC;
+ if (!strcmp(formatString, "uid")) return FORMAT_MODIFIER_UID;
+ if (!strcmp(formatString, "descriptive")) return FORMAT_MODIFIER_DESCRIPT;
/* clang-format on */
-#ifndef __MINGW32__
- else {
- extern char* tzname[2];
- static const char gmt[] = "GMT";
- char* cp = getenv(tz);
- if (cp) {
- cp = strdup(cp);
- }
- setenv(tz, formatString, 1);
- /*
- * Run tzset here to determine if the timezone is legitimate. If the
- * zone is GMT, check if that is what was asked for, if not then
- * did not match any on the system; report an error to caller.
- */
- tzset();
- if (!tzname[0] ||
- ((!strcmp(tzname[0], utc) || !strcmp(tzname[0], gmt)) /* error? */
- && strcasecmp(formatString, utc) && strcasecmp(formatString, gmt))) { /* ok */
- if (cp) {
- setenv(tz, cp, 1);
- } else {
- unsetenv(tz);
- }
- tzset();
- format = FORMAT_OFF;
- } else {
- format = FORMAT_MODIFIER_ZONE;
- }
- free(cp);
+#if !defined(__MINGW32__)
+ // Check whether the format string is actually a time zone. If tzname[0]
+ // is the empty string, that's tzset() signalling that it doesn't know
+ // the requested timezone.
+ TzSetter tz(formatString);
+ if (!*tzname[0]) {
+ tz.Reset();
+ } else {
+ // We keep the new time zone as a side effect!
+ return FORMAT_MODIFIER_ZONE;
}
#endif
- return format;
+ return FORMAT_OFF;
}
/**
@@ -433,8 +426,7 @@
return -1;
}
-#ifndef HAVE_STRSEP
-/* KISS replacement helper for below */
+#if defined(__MINGW32__) // Windows doesn't have strsep(3).
static char* strsep(char** stringp, const char* delim) {
char* token;
char* ret = *stringp;
@@ -1282,17 +1274,9 @@
if (!cp) {
continue;
}
- cp = getenv(tz);
- if (cp) {
- cp = strdup(cp);
- }
- setenv(tz, utc, 1);
- time.tv_sec = mktime(&tm);
- if (cp) {
- setenv(tz, cp, 1);
- free(cp);
- } else {
- unsetenv(tz);
+ {
+ TzSetter tz(cp);
+ time.tv_sec = mktime(&tm);
}
list = static_cast<conversionList*>(calloc(1, sizeof(conversionList)));
list_init(&list->node);
@@ -1503,7 +1487,7 @@
if (p_format->colored_output) {
prefixLen =
snprintf(prefixBuf, sizeof(prefixBuf), "\x1B[%dm", colorFromPri(entry->priority));
- prefixLen = MIN(prefixLen, sizeof(prefixBuf));
+ prefixLen = std::min(prefixLen, sizeof(prefixBuf));
const char suffixContents[] = "\x1B[0m";
strcpy(suffixBuf, suffixContents);
@@ -1543,7 +1527,7 @@
case FORMAT_PROCESS:
len = snprintf(suffixBuf + suffixLen, sizeof(suffixBuf) - suffixLen, " (%.*s)\n",
(int)entry->tagLen, entry->tag);
- suffixLen += MIN(len, sizeof(suffixBuf) - suffixLen);
+ suffixLen += std::min(len, sizeof(suffixBuf) - suffixLen);
len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, "%c(%s%5d) ", priChar,
uid, entry->pid);
break;
diff --git a/liblog/tests/logprint_test.cpp b/liblog/tests/logprint_test.cpp
index 72e53f9..e13934d 100644
--- a/liblog/tests/logprint_test.cpp
+++ b/liblog/tests/logprint_test.cpp
@@ -29,7 +29,7 @@
auto output_size = convertPrintable(nullptr, input, strlen(input));
EXPECT_EQ(output_size, strlen(input));
- char output[output_size];
+ char output[output_size + 1];
output_size = convertPrintable(output, input, strlen(input));
EXPECT_EQ(output_size, strlen(input));
@@ -43,7 +43,7 @@
auto output_size = convertPrintable(nullptr, input, strlen(input));
EXPECT_EQ(output_size, strlen(expected_output));
- char output[output_size];
+ char output[output_size + 1];
output_size = convertPrintable(output, input, strlen(input));
EXPECT_EQ(output_size, strlen(expected_output));
@@ -55,7 +55,7 @@
auto output_size = convertPrintable(nullptr, input, strlen(input));
EXPECT_EQ(output_size, strlen(input));
- char output[output_size];
+ char output[output_size + 1];
output_size = convertPrintable(output, input, strlen(input));
EXPECT_EQ(output_size, strlen(input));
@@ -69,7 +69,7 @@
auto output_size = convertPrintable(nullptr, input, strlen(input));
EXPECT_EQ(output_size, strlen(expected_output));
- char output[output_size];
+ char output[output_size + 1];
output_size = convertPrintable(output, input, strlen(input));
EXPECT_EQ(output_size, strlen(expected_output));
@@ -85,7 +85,7 @@
auto output_size = convertPrintable(nullptr, input, strlen(input));
EXPECT_EQ(output_size, strlen(expected_output));
- char output[output_size];
+ char output[output_size + 1];
output_size = convertPrintable(output, input, strlen(input));
EXPECT_EQ(output_size, strlen(expected_output));
diff --git a/logwrapper/Android.bp b/logwrapper/Android.bp
index 2799947..5b456ac 100644
--- a/logwrapper/Android.bp
+++ b/logwrapper/Android.bp
@@ -28,6 +28,8 @@
cc_library {
name: "liblogwrap",
defaults: ["logwrapper_defaults"],
+ ramdisk_available: true,
+ vendor_ramdisk_available: true,
recovery_available: true,
srcs: ["logwrap.cpp"],
shared_libs: [
diff --git a/rust/tests/config_log_level.rs b/rust/tests/config_log_level.rs
index 7a9a241..c4ff2d1 100644
--- a/rust/tests/config_log_level.rs
+++ b/rust/tests/config_log_level.rs
@@ -9,7 +9,7 @@
logger::Config::default()
.with_min_level(log::Level::Trace));
- assert_eq!(init_result, true);
+ assert!(init_result);
// Setting the level through the Config struct should impact both host and device
assert_eq!(log::max_level(), log::LevelFilter::Trace);
diff --git a/rust/tests/default_init.rs b/rust/tests/default_init.rs
index 413e8c8..837677c 100644
--- a/rust/tests/default_init.rs
+++ b/rust/tests/default_init.rs
@@ -1,6 +1,6 @@
#[test]
fn default_init() {
- assert_eq!(logger::init(Default::default()), true);
+ assert!(logger::init(Default::default()));
if cfg!(target_os = "android") {
// android_logger has default log level "off"
diff --git a/rust/tests/env_log_level.rs b/rust/tests/env_log_level.rs
index eb86d97..0534be3 100644
--- a/rust/tests/env_log_level.rs
+++ b/rust/tests/env_log_level.rs
@@ -3,7 +3,7 @@
#[test]
fn env_log_level() {
env::set_var("RUST_LOG", "debug");
- assert_eq!(logger::init(Default::default()), true);
+ assert!(logger::init(Default::default()));
if cfg!(target_os = "android") {
// android_logger does not read from environment variables
diff --git a/rust/tests/multiple_init.rs b/rust/tests/multiple_init.rs
index 0ac8b2f..7928dcf 100644
--- a/rust/tests/multiple_init.rs
+++ b/rust/tests/multiple_init.rs
@@ -3,6 +3,6 @@
let first_init = logger::init(Default::default());
let second_init = logger::init(Default::default());
- assert_eq!(first_init, true);
- assert_eq!(second_init, false);
+ assert!(first_init);
+ assert!(!second_init);
}
\ No newline at end of file