Home | History | Annotate | Line # | Download | only in fuzzer
      1 //===- FuzzerIOPosix.cpp - IO utils for Posix. ----------------------------===//
      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 implementation using Posix API.
     10 //===----------------------------------------------------------------------===//
     11 #include "FuzzerDefs.h"
     12 #if LIBFUZZER_POSIX || LIBFUZZER_FUCHSIA
     13 
     14 #include "FuzzerExtFunctions.h"
     15 #include "FuzzerIO.h"
     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 
     26 namespace fuzzer {
     27 
     28 bool 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 
     35 static bool 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 
     42 size_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 
     49 std::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 
     56 void ListFilesInDirRecursive(const std::string &Dir, long *Epoch,
     57                              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 
     82 char GetSeparator() {
     83   return '/';
     84 }
     85 
     86 FILE* OpenFile(int Fd, const char* Mode) {
     87   return fdopen(Fd, Mode);
     88 }
     89 
     90 int CloseFile(int fd) {
     91   return close(fd);
     92 }
     93 
     94 int DuplicateFile(int Fd) {
     95   return dup(Fd);
     96 }
     97 
     98 void RemoveFile(const std::string &Path) {
     99   unlink(Path.c_str());
    100 }
    101 
    102 void DiscardOutput(int Fd) {
    103   FILE* Temp = fopen("/dev/null", "w");
    104   if (!Temp)
    105     return;
    106   dup2(fileno(Temp), Fd);
    107   fclose(Temp);
    108 }
    109 
    110 intptr_t GetHandleFromFd(int fd) {
    111   return static_cast<intptr_t>(fd);
    112 }
    113 
    114 std::string DirName(const std::string &FileName) {
    115   char *Tmp = new char[FileName.size() + 1];
    116   memcpy(Tmp, FileName.c_str(), FileName.size() + 1);
    117   std::string Res = dirname(Tmp);
    118   delete [] Tmp;
    119   return Res;
    120 }
    121 
    122 std::string TmpDir() {
    123   if (auto Env = getenv("TMPDIR"))
    124     return Env;
    125   return "/tmp";
    126 }
    127 
    128 bool IsInterestingCoverageFile(const std::string &FileName) {
    129   if (FileName.find("compiler-rt/lib/") != std::string::npos)
    130     return false; // sanitizer internal.
    131   if (FileName.find("/usr/lib/") != std::string::npos)
    132     return false;
    133   if (FileName.find("/usr/include/") != std::string::npos)
    134     return false;
    135   if (FileName == "<null>")
    136     return false;
    137   return true;
    138 }
    139 
    140 
    141 void RawPrint(const char *Str) {
    142   write(2, Str, strlen(Str));
    143 }
    144 
    145 }  // namespace fuzzer
    146 
    147 #endif // LIBFUZZER_POSIX
    148