1 /* 2 * Copyright (C) 2012-2014 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 <stdlib.h> 18 19 #include <private/android_filesystem_config.h> 20 21 #include "FlushCommand.h" 22 #include "LogBuffer.h" 23 #include "LogBufferElement.h" 24 #include "LogCommand.h" 25 #include "LogReader.h" 26 #include "LogTimes.h" 27 #include "LogUtils.h" 28 29 // runSocketCommand is called once for every open client on the 30 // log reader socket. Here we manage and associated the reader 31 // client tracking and log region locks LastLogTimes list of 32 // LogTimeEntrys, and spawn a transitory per-client thread to 33 // work at filing data to the socket. 34 // 35 // global LogTimeEntry::wrlock() is used to protect access, 36 // reference counts are used to ensure that individual 37 // LogTimeEntry lifetime is managed when not protected. runSocketCommand(SocketClient * client)38void FlushCommand::runSocketCommand(SocketClient* client) { 39 LogTimeEntry* entry = nullptr; 40 LastLogTimes& times = mReader.logbuf().mTimes; 41 42 LogTimeEntry::wrlock(); 43 LastLogTimes::iterator it = times.begin(); 44 while (it != times.end()) { 45 entry = it->get(); 46 if (entry->mClient == client) { 47 if (!entry->isWatchingMultiple(mLogMask)) { 48 LogTimeEntry::unlock(); 49 return; 50 } 51 if (entry->mTimeout.tv_sec || entry->mTimeout.tv_nsec) { 52 if (mReader.logbuf().isMonotonic()) { 53 LogTimeEntry::unlock(); 54 return; 55 } 56 // If the user changes the time in a gross manner that 57 // invalidates the timeout, fall through and trigger. 58 log_time now(CLOCK_REALTIME); 59 if (((entry->mEnd + entry->mTimeout) > now) && 60 (now > entry->mEnd)) { 61 LogTimeEntry::unlock(); 62 return; 63 } 64 } 65 entry->triggerReader_Locked(); 66 LogTimeEntry::unlock(); 67 return; 68 } 69 it++; 70 } 71 72 LogTimeEntry::unlock(); 73 } 74 hasReadLogs(SocketClient * client)75bool FlushCommand::hasReadLogs(SocketClient* client) { 76 return clientHasLogCredentials(client); 77 } 78 clientHasSecurityCredentials(SocketClient * client)79static bool clientHasSecurityCredentials(SocketClient* client) { 80 return (client->getUid() == AID_SYSTEM) || (client->getGid() == AID_SYSTEM); 81 } 82 hasSecurityLogs(SocketClient * client)83bool FlushCommand::hasSecurityLogs(SocketClient* client) { 84 return clientHasSecurityCredentials(client); 85 } 86