Home | History | Annotate | Download | only in simpleperf
      1 /*
      2  * Copyright (C) 2015 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 "utils.h"
     18 
     19 #include <dirent.h>
     20 #include <errno.h>
     21 #include <fcntl.h>
     22 #include <stdarg.h>
     23 #include <stdio.h>
     24 #include <sys/stat.h>
     25 #include <unistd.h>
     26 
     27 #include <algorithm>
     28 #include <map>
     29 #include <string>
     30 
     31 #include <android-base/file.h>
     32 #include <android-base/logging.h>
     33 
     34 void OneTimeFreeAllocator::Clear() {
     35   for (auto& p : v_) {
     36     delete[] p;
     37   }
     38   v_.clear();
     39   cur_ = nullptr;
     40   end_ = nullptr;
     41 }
     42 
     43 const char* OneTimeFreeAllocator::AllocateString(const std::string& s) {
     44   size_t size = s.size() + 1;
     45   if (cur_ + size > end_) {
     46     size_t alloc_size = std::max(size, unit_size_);
     47     char* p = new char[alloc_size];
     48     v_.push_back(p);
     49     cur_ = p;
     50     end_ = p + alloc_size;
     51   }
     52   strcpy(cur_, s.c_str());
     53   const char* result = cur_;
     54   cur_ += size;
     55   return result;
     56 }
     57 
     58 
     59 FileHelper FileHelper::OpenReadOnly(const std::string& filename) {
     60     int fd = TEMP_FAILURE_RETRY(open(filename.c_str(), O_RDONLY | O_BINARY));
     61     return FileHelper(fd);
     62 }
     63 
     64 FileHelper FileHelper::OpenWriteOnly(const std::string& filename) {
     65     int fd = TEMP_FAILURE_RETRY(open(filename.c_str(), O_WRONLY | O_BINARY | O_CREAT, 0644));
     66     return FileHelper(fd);
     67 }
     68 
     69 FileHelper::~FileHelper() {
     70   if (fd_ != -1) {
     71     close(fd_);
     72   }
     73 }
     74 
     75 ArchiveHelper::ArchiveHelper(int fd, const std::string& debug_filename) : valid_(false) {
     76   int rc = OpenArchiveFd(fd, "", &handle_, false);
     77   if (rc == 0) {
     78     valid_ = true;
     79   } else {
     80     LOG(ERROR) << "Failed to open archive " << debug_filename << ": " << ErrorCodeString(rc);
     81   }
     82 }
     83 
     84 ArchiveHelper::~ArchiveHelper() {
     85   if (valid_) {
     86     CloseArchive(handle_);
     87   }
     88 }
     89 
     90 void PrintIndented(size_t indent, const char* fmt, ...) {
     91   va_list ap;
     92   va_start(ap, fmt);
     93   printf("%*s", static_cast<int>(indent * 2), "");
     94   vprintf(fmt, ap);
     95   va_end(ap);
     96 }
     97 
     98 bool IsPowerOfTwo(uint64_t value) {
     99   return (value != 0 && ((value & (value - 1)) == 0));
    100 }
    101 
    102 void GetEntriesInDir(const std::string& dirpath, std::vector<std::string>* files,
    103                      std::vector<std::string>* subdirs) {
    104   if (files != nullptr) {
    105     files->clear();
    106   }
    107   if (subdirs != nullptr) {
    108     subdirs->clear();
    109   }
    110   DIR* dir = opendir(dirpath.c_str());
    111   if (dir == nullptr) {
    112     PLOG(DEBUG) << "can't open dir " << dirpath;
    113     return;
    114   }
    115   dirent* entry;
    116   while ((entry = readdir(dir)) != nullptr) {
    117     if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
    118       continue;
    119     }
    120     if (IsDir(dirpath + std::string("/") + entry->d_name)) {
    121       if (subdirs != nullptr) {
    122         subdirs->push_back(entry->d_name);
    123       }
    124     } else {
    125       if (files != nullptr) {
    126         files->push_back(entry->d_name);
    127       }
    128     }
    129   }
    130   closedir(dir);
    131 }
    132 
    133 bool IsDir(const std::string& dirpath) {
    134   struct stat st;
    135   if (stat(dirpath.c_str(), &st) == 0) {
    136     if (S_ISDIR(st.st_mode)) {
    137       return true;
    138     }
    139   }
    140   return false;
    141 }
    142 
    143 bool IsRegularFile(const std::string& filename) {
    144   struct stat st;
    145   if (stat(filename.c_str(), &st) == 0) {
    146     if (S_ISREG(st.st_mode)) {
    147       return true;
    148     }
    149   }
    150   return false;
    151 }
    152 
    153 uint64_t GetFileSize(const std::string& filename) {
    154   struct stat st;
    155   if (stat(filename.c_str(), &st) == 0) {
    156     return static_cast<uint64_t>(st.st_size);
    157   }
    158   return 0;
    159 }
    160 
    161 bool MkdirWithParents(const std::string& path) {
    162   size_t prev_end = 0;
    163   while (prev_end < path.size()) {
    164     size_t next_end = path.find('/', prev_end + 1);
    165     if (next_end == std::string::npos) {
    166       break;
    167     }
    168     std::string dir_path = path.substr(0, next_end);
    169     if (!IsDir(dir_path)) {
    170 #if defined(_WIN32)
    171       int ret = mkdir(dir_path.c_str());
    172 #else
    173       int ret = mkdir(dir_path.c_str(), 0755);
    174 #endif
    175       if (ret != 0) {
    176         PLOG(ERROR) << "failed to create dir " << dir_path;
    177         return false;
    178       }
    179     }
    180     prev_end = next_end;
    181   }
    182   return true;
    183 }
    184 
    185 bool GetLogSeverity(const std::string& name, android::base::LogSeverity* severity) {
    186   static std::map<std::string, android::base::LogSeverity> log_severity_map = {
    187       {"verbose", android::base::VERBOSE},
    188       {"debug", android::base::DEBUG},
    189       {"warning", android::base::WARNING},
    190       {"error", android::base::ERROR},
    191       {"fatal", android::base::FATAL},
    192   };
    193   auto it = log_severity_map.find(name);
    194   if (it != log_severity_map.end()) {
    195     *severity = it->second;
    196     return true;
    197   }
    198   return false;
    199 }
    200 
    201 bool IsRoot() {
    202   static int is_root = -1;
    203   if (is_root == -1) {
    204 #if defined(__linux__)
    205     is_root = (getuid() == 0) ? 1 : 0;
    206 #else
    207     is_root = 0;
    208 #endif
    209   }
    210   return is_root == 1;
    211 }
    212