Planeshift
|
00001 // Copyright (c) 2013, Google Inc. 00002 // All rights reserved. 00003 // 00004 // Redistribution and use in source and binary forms, with or without 00005 // modification, are permitted provided that the following conditions are 00006 // met: 00007 // 00008 // * Redistributions of source code must retain the above copyright 00009 // notice, this list of conditions and the following disclaimer. 00010 // * Redistributions in binary form must reproduce the above 00011 // copyright notice, this list of conditions and the following disclaimer 00012 // in the documentation and/or other materials provided with the 00013 // distribution. 00014 // * Neither the name of Google Inc. nor the names of its 00015 // contributors may be used to endorse or promote products derived from 00016 // this software without specific prior written permission. 00017 // 00018 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00019 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00020 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00021 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00022 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00023 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00024 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00025 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00026 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00027 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00028 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 00030 #ifndef CLIENT_LINUX_MINIDUMP_WRITER_PROC_CPUINFO_READER_H_ 00031 #define CLIENT_LINUX_MINIDUMP_WRITER_PROC_CPUINFO_READER_H_ 00032 00033 #include <stdint.h> 00034 #include <assert.h> 00035 #include <string.h> 00036 00037 #include "client/linux/minidump_writer/line_reader.h" 00038 #include "common/linux/linux_libc_support.h" 00039 #include "third_party/lss/linux_syscall_support.h" 00040 00041 namespace google_breakpad { 00042 00043 // A class for reading /proc/cpuinfo without using fopen/fgets or other 00044 // functions which may allocate memory. 00045 class ProcCpuInfoReader { 00046 public: 00047 ProcCpuInfoReader(int fd) 00048 : line_reader_(fd), pop_count_(-1) { 00049 } 00050 00051 // Return the next field name, or NULL in case of EOF. 00052 // field: (output) Pointer to zero-terminated field name. 00053 // Returns true on success, or false on EOF or error (line too long). 00054 bool GetNextField(const char** field) { 00055 for (;;) { 00056 const char* line; 00057 unsigned line_len; 00058 00059 // Try to read next line. 00060 if (pop_count_ >= 0) { 00061 line_reader_.PopLine(pop_count_); 00062 pop_count_ = -1; 00063 } 00064 00065 if (!line_reader_.GetNextLine(&line, &line_len)) 00066 return false; 00067 00068 pop_count_ = static_cast<int>(line_len); 00069 00070 const char* line_end = line + line_len; 00071 00072 // Expected format: <field-name> <space>+ ':' <space> <value> 00073 // Note that: 00074 // - empty lines happen. 00075 // - <field-name> can contain spaces. 00076 // - some fields have an empty <value> 00077 char* sep = static_cast<char*>(my_memchr(line, ':', line_len)); 00078 if (sep == NULL) 00079 continue; 00080 00081 // Record the value. Skip leading space after the column to get 00082 // its start. 00083 const char* val = sep+1; 00084 while (val < line_end && my_isspace(*val)) 00085 val++; 00086 00087 value_ = val; 00088 value_len_ = static_cast<size_t>(line_end - val); 00089 00090 // Remove trailing spaces before the column to properly 0-terminate 00091 // the field name. 00092 while (sep > line && my_isspace(sep[-1])) 00093 sep--; 00094 00095 if (sep == line) 00096 continue; 00097 00098 // zero-terminate field name. 00099 *sep = '\0'; 00100 00101 *field = line; 00102 return true; 00103 } 00104 } 00105 00106 // Return the field value. This must be called after a successful 00107 // call to GetNextField(). 00108 const char* GetValue() { 00109 assert(value_); 00110 return value_; 00111 } 00112 00113 // Same as GetValue(), but also returns the length in characters of 00114 // the value. 00115 const char* GetValueAndLen(size_t* length) { 00116 assert(value_); 00117 *length = value_len_; 00118 return value_; 00119 } 00120 00121 private: 00122 LineReader line_reader_; 00123 int pop_count_; 00124 const char* value_; 00125 size_t value_len_; 00126 }; 00127 00128 } // namespace google_breakpad 00129 00130 #endif // CLIENT_LINUX_MINIDUMP_WRITER_PROC_CPUINFO_READER_H_