1 //===- FuzzerIO.cpp - IO utils. -------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // IO functions. 10 //===----------------------------------------------------------------------===// 11 #include "FuzzerInternal.h" 12 #include <iterator> 13 #include <fstream> 14 #include <dirent.h> 15 #include <sys/types.h> 16 #include <sys/stat.h> 17 #include <unistd.h> 18 #include <cstdarg> 19 #include <cstdio> 20 21 namespace fuzzer { 22 23 static long GetEpoch(const std::string &Path) { 24 struct stat St; 25 if (stat(Path.c_str(), &St)) 26 return 0; // Can't stat, be conservative. 27 return St.st_mtime; 28 } 29 30 static std::vector<std::string> ListFilesInDir(const std::string &Dir, 31 long *Epoch) { 32 std::vector<std::string> V; 33 if (Epoch) { 34 auto E = GetEpoch(Dir); 35 if (*Epoch >= E) return V; 36 *Epoch = E; 37 } 38 DIR *D = opendir(Dir.c_str()); 39 if (!D) { 40 Printf("No such directory: %s; exiting\n", Dir.c_str()); 41 exit(1); 42 } 43 while (auto E = readdir(D)) { 44 if (E->d_type == DT_REG || E->d_type == DT_LNK) 45 V.push_back(E->d_name); 46 } 47 closedir(D); 48 return V; 49 } 50 51 Unit FileToVector(const std::string &Path) { 52 std::ifstream T(Path); 53 if (!T) { 54 Printf("No such directory: %s; exiting\n", Path.c_str()); 55 exit(1); 56 } 57 return Unit((std::istreambuf_iterator<char>(T)), 58 std::istreambuf_iterator<char>()); 59 } 60 61 std::string FileToString(const std::string &Path) { 62 std::ifstream T(Path); 63 return std::string((std::istreambuf_iterator<char>(T)), 64 std::istreambuf_iterator<char>()); 65 } 66 67 void CopyFileToErr(const std::string &Path) { 68 Printf("%s", FileToString(Path).c_str()); 69 } 70 71 void WriteToFile(const Unit &U, const std::string &Path) { 72 // Use raw C interface because this function may be called from a sig handler. 73 FILE *Out = fopen(Path.c_str(), "w"); 74 if (!Out) return; 75 fwrite(U.data(), sizeof(U[0]), U.size(), Out); 76 fclose(Out); 77 } 78 79 void ReadDirToVectorOfUnits(const char *Path, std::vector<Unit> *V, 80 long *Epoch) { 81 long E = Epoch ? *Epoch : 0; 82 for (auto &X : ListFilesInDir(Path, Epoch)) { 83 auto FilePath = DirPlusFile(Path, X); 84 if (Epoch && GetEpoch(FilePath) < E) continue; 85 V->push_back(FileToVector(FilePath)); 86 } 87 } 88 89 std::string DirPlusFile(const std::string &DirPath, 90 const std::string &FileName) { 91 return DirPath + "/" + FileName; 92 } 93 94 void Printf(const char *Fmt, ...) { 95 va_list ap; 96 va_start(ap, Fmt); 97 vfprintf(stderr, Fmt, ap); 98 va_end(ap); 99 } 100 101 } // namespace fuzzer 102