Home | History | Annotate | Download | only in Fuzzer
      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