void LogKlog::sniffTime(log_time &now, const char **buf, bool reverse) { const char *cp; if ((cp = now.strptime(*buf, "[ %s.%q]"))) { static const char suspend[] = "PM: suspend entry "; static const char resume[] = "PM: suspend exit "; static const char healthd[] = "healthd: battery "; static const char suspended[] = "Suspended for "; if (isspace(*cp)) { ++cp; } if (!strncmp(cp, suspend, sizeof(suspend) - 1)) { calculateCorrection(now, cp + sizeof(suspend) - 1); } else if (!strncmp(cp, resume, sizeof(resume) - 1)) { calculateCorrection(now, cp + sizeof(resume) - 1); } else if (!strncmp(cp, healthd, sizeof(healthd) - 1)) { // look for " 2???-??-?? ??:??:??.????????? ???" const char *tp; for (tp = cp + sizeof(healthd) - 1; *tp && (*tp != '\n'); ++tp) { if ((tp[0] == ' ') && (tp[1] == '2') && (tp[5] == '-')) { calculateCorrection(now, tp + 1); break; } } } else if (!strncmp(cp, suspended, sizeof(suspended) - 1)) { log_time real; char *endp; real.tv_sec = strtol(cp + sizeof(suspended) - 1, &endp, 10); if (*endp == '.') { real.tv_nsec = strtol(endp + 1, &endp, 10) * 1000000L; if (reverse) { correction -= real; } else { correction += real; } } } convertMonotonicToReal(now); *buf = cp; } else { now = log_time(CLOCK_REALTIME); } }
void LogKlog::sniffTime(log_time &now, const char **buf, size_t len, bool reverse) { const char *cp = now.strptime(*buf, "[ %s.%q]"); if (cp && (cp >= &(*buf)[len])) { cp = NULL; } if (cp) { static const char healthd[] = "healthd"; static const char battery[] = ": battery "; len -= cp - *buf; if (len && isspace(*cp)) { ++cp; --len; } *buf = cp; if (isMonotonic()) { return; } const char *b; if (((b = strnstr(cp, len, suspendStr))) && ((size_t)((b += sizeof(suspendStr) - 1) - cp) < len)) { len -= b - cp; calculateCorrection(now, b, len); } else if (((b = strnstr(cp, len, resumeStr))) && ((size_t)((b += sizeof(resumeStr) - 1) - cp) < len)) { len -= b - cp; calculateCorrection(now, b, len); } else if (((b = strnstr(cp, len, healthd))) && ((size_t)((b += sizeof(healthd) - 1) - cp) < len) && ((b = strnstr(b, len -= b - cp, battery))) && ((size_t)((b += sizeof(battery) - 1) - cp) < len)) { // NB: healthd is roughly 150us late, so we use it instead to // trigger a check for ntp-induced or hardware clock drift. log_time real(CLOCK_REALTIME); log_time mono(CLOCK_MONOTONIC); correction = (real < mono) ? log_time::EPOCH : (real - mono); } else if (((b = strnstr(cp, len, suspendedStr))) && ((size_t)((b += sizeof(suspendStr) - 1) - cp) < len)) { len -= b - cp; log_time real; char *endp; real.tv_sec = strtol(b, &endp, 10); if ((*endp == '.') && ((size_t)(endp - b) < len)) { unsigned long multiplier = NS_PER_SEC; real.tv_nsec = 0; len -= endp - b; while (--len && isdigit(*++endp) && (multiplier /= 10)) { real.tv_nsec += (*endp - '0') * multiplier; } if (reverse) { if (real > correction) { correction = log_time::EPOCH; } else { correction -= real; } } else { correction += real; } } } convertMonotonicToReal(now); } else { if (isMonotonic()) { now = log_time(CLOCK_MONOTONIC); } else { now = log_time(CLOCK_REALTIME); } } }
void LogKlog::sniffTime(log_time& now, const char*& buf, ssize_t len, bool reverse) { if (len <= 0) return; const char* cp = nullptr; if ((len > 10) && (*buf == '[')) { cp = now.strptime(buf, "[ %s.%q]"); // can index beyond buffer bounds if (cp && (cp > &buf[len - 1])) cp = nullptr; } if (cp) { len -= cp - buf; if ((len > 0) && isspace(*cp)) { ++cp; --len; } buf = cp; if (isMonotonic()) return; const char* b; if (((b = android::strnstr(cp, len, suspendStr))) && (((b += strlen(suspendStr)) - cp) < len)) { len -= b - cp; calculateCorrection(now, b, len); } else if (((b = android::strnstr(cp, len, resumeStr))) && (((b += strlen(resumeStr)) - cp) < len)) { len -= b - cp; calculateCorrection(now, b, len); } else if (((b = android::strnstr(cp, len, healthdStr))) && (((b += strlen(healthdStr)) - cp) < len) && ((b = android::strnstr(b, len -= b - cp, batteryStr))) && (((b += strlen(batteryStr)) - cp) < len)) { // NB: healthd is roughly 150us late, so we use it instead to // trigger a check for ntp-induced or hardware clock drift. log_time real(CLOCK_REALTIME); log_time mono(CLOCK_MONOTONIC); correction = (real < mono) ? log_time::EPOCH : (real - mono); } else if (((b = android::strnstr(cp, len, suspendedStr))) && (((b += strlen(suspendStr)) - cp) < len)) { len -= b - cp; log_time real; char* endp; real.tv_sec = strtol(b, &endp, 10); if ((*endp == '.') && ((endp - b) < len)) { unsigned long multiplier = NS_PER_SEC; real.tv_nsec = 0; len -= endp - b; while (--len && isdigit(*++endp) && (multiplier /= 10)) { real.tv_nsec += (*endp - '0') * multiplier; } if (reverse) { if (real > correction) { correction = log_time::EPOCH; } else { correction -= real; } } else { correction += real; } } } convertMonotonicToReal(now); } else { if (isMonotonic()) { now = log_time(CLOCK_MONOTONIC); } else { now = log_time(CLOCK_REALTIME); } } }
void LogKlog::sniffTime(log_time &now, const char **buf, size_t len, bool reverse) { const char *cp = now.strptime(*buf, "[ %s.%q]"); if (cp && (cp >= &(*buf)[len])) { cp = NULL; } len -= cp - *buf; if (cp) { static const char healthd[] = "healthd"; static const char battery[] = ": battery "; if (len && isspace(*cp)) { ++cp; --len; } *buf = cp; const char *b; if (((b = strnstr(cp, len, suspendStr))) && ((size_t)((b += sizeof(suspendStr) - 1) - cp) < len)) { len -= b - cp; calculateCorrection(now, b, len); } else if (((b = strnstr(cp, len, resumeStr))) && ((size_t)((b += sizeof(resumeStr) - 1) - cp) < len)) { len -= b - cp; calculateCorrection(now, b, len); } else if (((b = strnstr(cp, len, healthd))) && ((size_t)((b += sizeof(healthd) - 1) - cp) < len) && ((b = strnstr(b, len -= b - cp, battery))) && ((size_t)((b += sizeof(battery) - 1) - cp) < len)) { len -= b - cp; // NB: healthd is roughly 150us late, worth the price to deal with // ntp-induced or hardware clock drift. // look for " 2???-??-?? ??:??:??.????????? ???" for (; len && *b && (*b != '\n'); ++b, --len) { if ((b[0] == ' ') && (b[1] == '2') && (b[5] == '-')) { calculateCorrection(now, b + 1, len - 1); break; } } } else if (((b = strnstr(cp, len, suspendedStr))) && ((size_t)((b += sizeof(suspendStr) - 1) - cp) < len)) { len -= b - cp; log_time real; char *endp; real.tv_sec = strtol(b, &endp, 10); if ((*endp == '.') && ((size_t)(endp - b) < len)) { unsigned long multiplier = NS_PER_SEC; real.tv_nsec = 0; len -= endp - b; while (--len && isdigit(*++endp) && (multiplier /= 10)) { real.tv_nsec += (*endp - '0') * multiplier; } if (reverse) { correction -= real; } else { correction += real; } } } convertMonotonicToReal(now); } else { now = log_time(CLOCK_REALTIME); } }