LogReader.cpp revision 3e76e0a49760c4970b7cda6153e51026af98e4f3
1/* 2 * Copyright (C) 2012-2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <poll.h> 18#include <sys/socket.h> 19#include <cutils/sockets.h> 20 21#include "LogReader.h" 22#include "FlushCommand.h" 23 24LogReader::LogReader(LogBuffer *logbuf) 25 : SocketListener("logdr", true) 26 , mLogbuf(*logbuf) 27{ } 28 29// When we are notified a new log entry is available, inform 30// all of our listening sockets. 31void LogReader::notifyNewLog() { 32 FlushCommand command(*this); 33 runOnEachSocket(&command); 34} 35 36bool LogReader::onDataAvailable(SocketClient *cli) { 37 char buffer[255]; 38 39 int len = read(cli->getSocket(), buffer, sizeof(buffer) - 1); 40 if (len <= 0) { 41 doSocketDelete(cli); 42 return false; 43 } 44 buffer[len] = '\0'; 45 46 unsigned long tail = 0; 47 static const char _tail[] = " tail="; 48 char *cp = strstr(buffer, _tail); 49 if (cp) { 50 tail = atol(cp + sizeof(_tail) - 1); 51 } 52 53 unsigned int logMask = -1; 54 static const char _logIds[] = " lids="; 55 cp = strstr(buffer, _logIds); 56 if (cp) { 57 logMask = 0; 58 cp += sizeof(_logIds) - 1; 59 while (*cp && *cp != '\0') { 60 int val = 0; 61 while (('0' <= *cp) && (*cp <= '9')) { 62 val *= 10; 63 val += *cp - '0'; 64 ++cp; 65 } 66 logMask |= 1 << val; 67 if (*cp != ',') { 68 break; 69 } 70 ++cp; 71 } 72 } 73 74 pid_t pid = 0; 75 static const char _pid[] = " pid="; 76 cp = strstr(buffer, _pid); 77 if (cp) { 78 pid = atol(cp + sizeof(_pid) - 1); 79 } 80 81 bool nonBlock = false; 82 if (strncmp(buffer, "dumpAndClose", 12) == 0) { 83 nonBlock = true; 84 } 85 86 FlushCommand command(*this, nonBlock, tail, logMask, pid); 87 command.runSocketCommand(cli); 88 return true; 89} 90 91void LogReader::doSocketDelete(SocketClient *cli) { 92 LastLogTimes × = mLogbuf.mTimes; 93 LogTimeEntry::lock(); 94 LastLogTimes::iterator it = times.begin(); 95 while(it != times.end()) { 96 LogTimeEntry *entry = (*it); 97 if (entry->mClient == cli) { 98 times.erase(it); 99 entry->release_Locked(); 100 break; 101 } 102 it++; 103 } 104 LogTimeEntry::unlock(); 105} 106