Planeshift
|
00001 // Copyright (c) 2009, 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_DIRECTORY_READER_H_ 00031 #define CLIENT_LINUX_MINIDUMP_WRITER_DIRECTORY_READER_H_ 00032 00033 #include <stdint.h> 00034 #include <unistd.h> 00035 #include <limits.h> 00036 #include <assert.h> 00037 #include <errno.h> 00038 #include <string.h> 00039 00040 #include "common/linux/linux_libc_support.h" 00041 #include "third_party/lss/linux_syscall_support.h" 00042 00043 namespace google_breakpad { 00044 00045 // A class for enumerating a directory without using diropen/readdir or other 00046 // functions which may allocate memory. 00047 class DirectoryReader { 00048 public: 00049 DirectoryReader(int fd) 00050 : fd_(fd), 00051 buf_used_(0) { 00052 } 00053 00054 // Return the next entry from the directory 00055 // name: (output) the NUL terminated entry name 00056 // 00057 // Returns true iff successful (false on EOF). 00058 // 00059 // After calling this, one must call |PopEntry| otherwise you'll get the same 00060 // entry over and over. 00061 bool GetNextEntry(const char** name) { 00062 struct kernel_dirent* const dent = 00063 reinterpret_cast<kernel_dirent*>(buf_); 00064 00065 if (buf_used_ == 0) { 00066 // need to read more entries. 00067 const int n = sys_getdents(fd_, dent, sizeof(buf_)); 00068 if (n < 0) { 00069 return false; 00070 } else if (n == 0) { 00071 hit_eof_ = true; 00072 } else { 00073 buf_used_ += n; 00074 } 00075 } 00076 00077 if (buf_used_ == 0 && hit_eof_) 00078 return false; 00079 00080 assert(buf_used_ > 0); 00081 00082 *name = dent->d_name; 00083 return true; 00084 } 00085 00086 void PopEntry() { 00087 if (!buf_used_) 00088 return; 00089 00090 const struct kernel_dirent* const dent = 00091 reinterpret_cast<kernel_dirent*>(buf_); 00092 00093 buf_used_ -= dent->d_reclen; 00094 my_memmove(buf_, buf_ + dent->d_reclen, buf_used_); 00095 } 00096 00097 private: 00098 const int fd_; 00099 bool hit_eof_; 00100 unsigned buf_used_; 00101 uint8_t buf_[sizeof(struct kernel_dirent) + NAME_MAX + 1]; 00102 }; 00103 00104 } // namespace google_breakpad 00105 00106 #endif // CLIENT_LINUX_MINIDUMP_WRITER_DIRECTORY_READER_H_