brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.5 KiB · f145ddd Raw
181 lines · cpp
1//===- FuzzerIOPosix.cpp - IO utils for Posix. ----------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8// IO functions implementation using Posix API.9//===----------------------------------------------------------------------===//10#include "FuzzerPlatform.h"11#if LIBFUZZER_POSIX || LIBFUZZER_FUCHSIA12 13#include "FuzzerExtFunctions.h"14#include "FuzzerIO.h"15#include <cerrno>16#include <cstdarg>17#include <cstdio>18#include <dirent.h>19#include <fstream>20#include <iterator>21#include <libgen.h>22#include <sys/stat.h>23#include <sys/types.h>24#include <unistd.h>25 26namespace fuzzer {27 28bool IsFile(const std::string &Path) {29  struct stat St;30  if (stat(Path.c_str(), &St))31    return false;32  return S_ISREG(St.st_mode);33}34 35bool IsDirectory(const std::string &Path) {36  struct stat St;37  if (stat(Path.c_str(), &St))38    return false;39  return S_ISDIR(St.st_mode);40}41 42size_t FileSize(const std::string &Path) {43  struct stat St;44  if (stat(Path.c_str(), &St))45    return 0;46  return St.st_size;47}48 49std::string Basename(const std::string &Path) {50  size_t Pos = Path.rfind(GetSeparator());51  if (Pos == std::string::npos) return Path;52  assert(Pos < Path.size());53  return Path.substr(Pos + 1);54}55 56void ListFilesInDirRecursive(const std::string &Dir, long *Epoch,57                             std::vector<std::string> *V, bool TopDir) {58  auto E = GetEpoch(Dir);59  if (Epoch)60    if (E && *Epoch >= E) return;61 62  DIR *D = opendir(Dir.c_str());63  if (!D) {64    Printf("%s: %s; exiting\n", strerror(errno), Dir.c_str());65    exit(1);66  }67  while (auto E = readdir(D)) {68    std::string Path = DirPlusFile(Dir, E->d_name);69    if (E->d_type == DT_REG || E->d_type == DT_LNK ||70        (E->d_type == DT_UNKNOWN && IsFile(Path)))71      V->push_back(Path);72    else if ((E->d_type == DT_DIR ||73             (E->d_type == DT_UNKNOWN && IsDirectory(Path))) &&74             *E->d_name != '.')75      ListFilesInDirRecursive(Path, Epoch, V, false);76  }77  closedir(D);78  if (Epoch && TopDir)79    *Epoch = E;80}81 82void IterateDirRecursive(const std::string &Dir,83                         void (*DirPreCallback)(const std::string &Dir),84                         void (*DirPostCallback)(const std::string &Dir),85                         void (*FileCallback)(const std::string &Dir)) {86  DirPreCallback(Dir);87  DIR *D = opendir(Dir.c_str());88  if (!D) return;89  while (auto E = readdir(D)) {90    std::string Path = DirPlusFile(Dir, E->d_name);91    if (E->d_type == DT_REG || E->d_type == DT_LNK ||92        (E->d_type == DT_UNKNOWN && IsFile(Path)))93      FileCallback(Path);94    else if ((E->d_type == DT_DIR ||95             (E->d_type == DT_UNKNOWN && IsDirectory(Path))) &&96             *E->d_name != '.')97      IterateDirRecursive(Path, DirPreCallback, DirPostCallback, FileCallback);98  }99  closedir(D);100  DirPostCallback(Dir);101}102 103char GetSeparator() {104  return '/';105}106 107bool IsSeparator(char C) {108  return C == '/';109}110 111FILE* OpenFile(int Fd, const char* Mode) {112  return fdopen(Fd, Mode);113}114 115int CloseFile(int fd) {116  return close(fd);117}118 119int DuplicateFile(int Fd) {120  return dup(Fd);121}122 123void RemoveFile(const std::string &Path) {124  unlink(Path.c_str());125}126 127void RenameFile(const std::string &OldPath, const std::string &NewPath) {128  rename(OldPath.c_str(), NewPath.c_str());129}130 131intptr_t GetHandleFromFd(int fd) {132  return static_cast<intptr_t>(fd);133}134 135std::string DirName(const std::string &FileName) {136  char *Tmp = new char[FileName.size() + 1];137  memcpy(Tmp, FileName.c_str(), FileName.size() + 1);138  std::string Res = dirname(Tmp);139  delete [] Tmp;140  return Res;141}142 143std::string TmpDir() {144  if (auto Env = getenv("TMPDIR"))145    return Env;146  return "/tmp";147}148 149bool IsInterestingCoverageFile(const std::string &FileName) {150  if (FileName.find("compiler-rt/lib/") != std::string::npos)151    return false; // sanitizer internal.152  if (FileName.find("/usr/lib/") != std::string::npos)153    return false;154  if (FileName.find("/usr/include/") != std::string::npos)155    return false;156  if (FileName == "<null>")157    return false;158  return true;159}160 161void RawPrint(const char *Str) {162  (void)write(2, Str, strlen(Str));163}164 165void MkDir(const std::string &Path) {166  mkdir(Path.c_str(), 0700);167}168 169void RmDir(const std::string &Path) {170  rmdir(Path.c_str());171}172 173const std::string &getDevNull() {174  static const std::string devNull = "/dev/null";175  return devNull;176}177 178}  // namespace fuzzer179 180#endif // LIBFUZZER_POSIX181