// Parse the tags out of the file. static int parseMapLines(EventTagMap* map, size_t which) { const char* cp = static_cast<char*>(map->mapAddr[which]); size_t len = map->mapLen[which]; const char* endp = cp + len; // insist on EOL at EOF; simplifies parsing and null-termination if (!len || (*(endp - 1) != '\n')) { #ifdef DEBUG fprintf(stderr, OUT_TAG ": map file %zu[%zu] missing EOL on last line\n", which, len); #endif if (which) { // do not propagate errors for other files return 0; } errno = EINVAL; return -1; } bool lineStart = true; int lineNum = 1; while (cp < endp) { if (*cp == '\n') { lineStart = true; lineNum++; } else if (lineStart) { if (*cp == '#') { // comment; just scan to end lineStart = false; } else if (isdigit(*cp)) { // looks like a tag; scan it out if (scanTagLine(map, cp, lineNum) != 0) { if (!which || (errno != EMLINK)) { return -1; } } lineNum++; // we eat the '\n' // leave lineStart==true } else if (isspace(*cp)) { // looks like leading whitespace; keep scanning } else { fprintf(stderr, OUT_TAG ": unexpected chars (0x%02x) in tag number on line %d\n", *cp, lineNum); errno = EINVAL; return -1; } } else { // this is a blank or comment line } cp++; } return 0; }
/* * Parse the tags out of the file. */ static int parseMapLines(EventTagMap* map) { int tagNum, lineStart, lineNum; char* cp; char* endp; cp = (char*) map->mapAddr; endp = cp + map->mapLen; /* insist on EOL at EOF; simplifies parsing and null-termination */ if (*(endp-1) != '\n') { return -1; } tagNum = 0; lineStart = 1; lineNum = 1; while (cp < endp) { //printf("{%02x}", *cp); fflush(stdout); if (*cp == '\n') { lineStart = 1; lineNum++; } else if (lineStart) { if (*cp == '#') { /* comment; just scan to end */ lineStart = 0; } else if (isCharDigit(*cp)) { /* looks like a tag; scan it out */ if (tagNum >= map->numTags) { return -1; } if (scanTagLine(&cp, &map->tagArray[tagNum], lineNum) != 0) return -1; tagNum++; lineNum++; // we eat the '\n' /* leave lineStart==1 */ } else if (isCharWhitespace(*cp)) { /* looks like leading whitespace; keep scanning */ } else { return -1; } } else { /* this is a blank or comment line */ } cp++; } if (tagNum != map->numTags) { return -1; } return 0; }
// Cache miss, go to logd to acquire a public reference. // Because we lack access to a SHARED PUBLIC /dev/event-log-tags file map? static const TagFmt* __getEventTag(EventTagMap* map, unsigned int tag) { // call event tag service to arrange for a new tag char* buf = NULL; // Can not use android::base::StringPrintf, asprintf + free instead. static const char command_template[] = "getEventTag id=%u"; int ret = asprintf(&buf, command_template, tag); if (ret > 0) { // Add some buffer margin for an estimate of the full return content. size_t size = ret - strlen(command_template) + strlen("65535\n4294967295\t?\t\t\t?\t# uid=32767\n\n\f?success?"); if (size > (size_t)ret) { char* np = static_cast<char*>(realloc(buf, size)); if (np) { buf = np; } else { size = ret; } } else { size = ret; } // Ask event log tag service for an existing entry if (__send_log_msg(buf, size) >= 0) { buf[size - 1] = '\0'; char* ep; unsigned long val = strtoul(buf, &ep, 10); // return size const char* cp = ep; if ((buf != cp) && (val > 0) && (*cp == '\n')) { // truncation OK ++cp; if (!scanTagLine(map, cp, 0)) { free(buf); return map->find(tag); } } } free(buf); } return NULL; }