1 1.1 kamil //===- FuzzerIOPosix.cpp - IO utils for Posix. ----------------------------===// 2 1.1 kamil // 3 1.1 kamil // The LLVM Compiler Infrastructure 4 1.1 kamil // 5 1.1 kamil // This file is distributed under the University of Illinois Open Source 6 1.1 kamil // License. See LICENSE.TXT for details. 7 1.1 kamil // 8 1.1 kamil //===----------------------------------------------------------------------===// 9 1.1 kamil // IO functions implementation using Posix API. 10 1.1 kamil //===----------------------------------------------------------------------===// 11 1.1 kamil #include "FuzzerDefs.h" 12 1.1 kamil #if LIBFUZZER_POSIX || LIBFUZZER_FUCHSIA 13 1.1 kamil 14 1.1 kamil #include "FuzzerExtFunctions.h" 15 1.1 kamil #include "FuzzerIO.h" 16 1.1 kamil #include <cstdarg> 17 1.1 kamil #include <cstdio> 18 1.1 kamil #include <dirent.h> 19 1.1 kamil #include <fstream> 20 1.1 kamil #include <iterator> 21 1.1 kamil #include <libgen.h> 22 1.1 kamil #include <sys/stat.h> 23 1.1 kamil #include <sys/types.h> 24 1.1 kamil #include <unistd.h> 25 1.1 kamil 26 1.1 kamil namespace fuzzer { 27 1.1 kamil 28 1.1 kamil bool IsFile(const std::string &Path) { 29 1.1 kamil struct stat St; 30 1.1 kamil if (stat(Path.c_str(), &St)) 31 1.1 kamil return false; 32 1.1 kamil return S_ISREG(St.st_mode); 33 1.1 kamil } 34 1.1 kamil 35 1.1 kamil static bool IsDirectory(const std::string &Path) { 36 1.1 kamil struct stat St; 37 1.1 kamil if (stat(Path.c_str(), &St)) 38 1.1 kamil return false; 39 1.1 kamil return S_ISDIR(St.st_mode); 40 1.1 kamil } 41 1.1 kamil 42 1.1 kamil size_t FileSize(const std::string &Path) { 43 1.1 kamil struct stat St; 44 1.1 kamil if (stat(Path.c_str(), &St)) 45 1.1 kamil return 0; 46 1.1 kamil return St.st_size; 47 1.1 kamil } 48 1.1 kamil 49 1.1 kamil std::string Basename(const std::string &Path) { 50 1.1 kamil size_t Pos = Path.rfind(GetSeparator()); 51 1.1 kamil if (Pos == std::string::npos) return Path; 52 1.1 kamil assert(Pos < Path.size()); 53 1.1 kamil return Path.substr(Pos + 1); 54 1.1 kamil } 55 1.1 kamil 56 1.1 kamil void ListFilesInDirRecursive(const std::string &Dir, long *Epoch, 57 1.1 kamil Vector<std::string> *V, bool TopDir) { 58 1.1 kamil auto E = GetEpoch(Dir); 59 1.1 kamil if (Epoch) 60 1.1 kamil if (E && *Epoch >= E) return; 61 1.1 kamil 62 1.1 kamil DIR *D = opendir(Dir.c_str()); 63 1.1 kamil if (!D) { 64 1.1 kamil Printf("%s: %s; exiting\n", strerror(errno), Dir.c_str()); 65 1.1 kamil exit(1); 66 1.1 kamil } 67 1.1 kamil while (auto E = readdir(D)) { 68 1.1 kamil std::string Path = DirPlusFile(Dir, E->d_name); 69 1.1 kamil if (E->d_type == DT_REG || E->d_type == DT_LNK || 70 1.1 kamil (E->d_type == DT_UNKNOWN && IsFile(Path))) 71 1.1 kamil V->push_back(Path); 72 1.1 kamil else if ((E->d_type == DT_DIR || 73 1.1 kamil (E->d_type == DT_UNKNOWN && IsDirectory(Path))) && 74 1.1 kamil *E->d_name != '.') 75 1.1 kamil ListFilesInDirRecursive(Path, Epoch, V, false); 76 1.1 kamil } 77 1.1 kamil closedir(D); 78 1.1 kamil if (Epoch && TopDir) 79 1.1 kamil *Epoch = E; 80 1.1 kamil } 81 1.1 kamil 82 1.1 kamil char GetSeparator() { 83 1.1 kamil return '/'; 84 1.1 kamil } 85 1.1 kamil 86 1.1 kamil FILE* OpenFile(int Fd, const char* Mode) { 87 1.1 kamil return fdopen(Fd, Mode); 88 1.1 kamil } 89 1.1 kamil 90 1.1 kamil int CloseFile(int fd) { 91 1.1 kamil return close(fd); 92 1.1 kamil } 93 1.1 kamil 94 1.1 kamil int DuplicateFile(int Fd) { 95 1.1 kamil return dup(Fd); 96 1.1 kamil } 97 1.1 kamil 98 1.1 kamil void RemoveFile(const std::string &Path) { 99 1.1 kamil unlink(Path.c_str()); 100 1.1 kamil } 101 1.1 kamil 102 1.1 kamil void DiscardOutput(int Fd) { 103 1.1 kamil FILE* Temp = fopen("/dev/null", "w"); 104 1.1 kamil if (!Temp) 105 1.1 kamil return; 106 1.1 kamil dup2(fileno(Temp), Fd); 107 1.1 kamil fclose(Temp); 108 1.1 kamil } 109 1.1 kamil 110 1.1 kamil intptr_t GetHandleFromFd(int fd) { 111 1.1 kamil return static_cast<intptr_t>(fd); 112 1.1 kamil } 113 1.1 kamil 114 1.1 kamil std::string DirName(const std::string &FileName) { 115 1.1 kamil char *Tmp = new char[FileName.size() + 1]; 116 1.1 kamil memcpy(Tmp, FileName.c_str(), FileName.size() + 1); 117 1.1 kamil std::string Res = dirname(Tmp); 118 1.1 kamil delete [] Tmp; 119 1.1 kamil return Res; 120 1.1 kamil } 121 1.1 kamil 122 1.1 kamil std::string TmpDir() { 123 1.1 kamil if (auto Env = getenv("TMPDIR")) 124 1.1 kamil return Env; 125 1.1 kamil return "/tmp"; 126 1.1 kamil } 127 1.1 kamil 128 1.1 kamil bool IsInterestingCoverageFile(const std::string &FileName) { 129 1.1 kamil if (FileName.find("compiler-rt/lib/") != std::string::npos) 130 1.1 kamil return false; // sanitizer internal. 131 1.1 kamil if (FileName.find("/usr/lib/") != std::string::npos) 132 1.1 kamil return false; 133 1.1 kamil if (FileName.find("/usr/include/") != std::string::npos) 134 1.1 kamil return false; 135 1.1 kamil if (FileName == "<null>") 136 1.1 kamil return false; 137 1.1 kamil return true; 138 1.1 kamil } 139 1.1 kamil 140 1.1 kamil 141 1.1 kamil void RawPrint(const char *Str) { 142 1.1 kamil write(2, Str, strlen(Str)); 143 1.1 kamil } 144 1.1 kamil 145 1.1 kamil } // namespace fuzzer 146 1.1 kamil 147 1.1 kamil #endif // LIBFUZZER_POSIX 148