blob: 4bb2df5d71ae6f9f25eb693beac53b62287ed89e [file] [log] [blame]
Aaron Ballmanef116982015-01-29 16:58:29 +00001//===- 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"
Kostya Serebryany5b266a82015-02-04 19:10:20 +000012#include <iterator>
Aaron Ballmanef116982015-01-29 16:58:29 +000013#include <fstream>
14#include <dirent.h>
Kostya Serebryany1ac80552015-05-08 21:30:55 +000015#include <sys/types.h>
16#include <sys/stat.h>
17#include <unistd.h>
Kostya Serebryany20e9bcb2015-05-23 01:07:46 +000018#include <cstdio>
Kostya Serebryany1ac80552015-05-08 21:30:55 +000019
Aaron Ballmanef116982015-01-29 16:58:29 +000020namespace fuzzer {
21
Kostya Serebryany1ac80552015-05-08 21:30:55 +000022static long GetEpoch(const std::string &Path) {
23 struct stat St;
Kostya Serebryany9cdea942015-09-08 20:36:33 +000024 if (stat(Path.c_str(), &St))
25 return 0; // Can't stat, be conservative.
Kostya Serebryany1ac80552015-05-08 21:30:55 +000026 return St.st_mtime;
27}
28
29static std::vector<std::string> ListFilesInDir(const std::string &Dir,
30 long *Epoch) {
Aaron Ballmanef116982015-01-29 16:58:29 +000031 std::vector<std::string> V;
Kostya Serebryany1ac80552015-05-08 21:30:55 +000032 if (Epoch) {
Kostya Serebryany06c199a2015-08-26 21:55:19 +000033 auto E = GetEpoch(Dir);
Kostya Serebryany1ac80552015-05-08 21:30:55 +000034 if (*Epoch >= E) return V;
35 *Epoch = E;
36 }
Aaron Ballmanef116982015-01-29 16:58:29 +000037 DIR *D = opendir(Dir.c_str());
Kostya Serebryany86e4a3e2015-07-18 00:03:37 +000038 if (!D) {
39 Printf("No such directory: %s; exiting\n", Dir.c_str());
40 exit(1);
41 }
Aaron Ballmanef116982015-01-29 16:58:29 +000042 while (auto E = readdir(D)) {
43 if (E->d_type == DT_REG || E->d_type == DT_LNK)
44 V.push_back(E->d_name);
45 }
46 closedir(D);
47 return V;
48}
49
50Unit FileToVector(const std::string &Path) {
51 std::ifstream T(Path);
Kostya Serebryanyb91c62b2015-10-16 22:41:47 +000052 if (!T) {
53 Printf("No such directory: %s; exiting\n", Path.c_str());
54 exit(1);
55 }
Aaron Ballmanef116982015-01-29 16:58:29 +000056 return Unit((std::istreambuf_iterator<char>(T)),
57 std::istreambuf_iterator<char>());
58}
59
Kostya Serebryany52a788e2015-03-31 20:13:20 +000060std::string FileToString(const std::string &Path) {
61 std::ifstream T(Path);
62 return std::string((std::istreambuf_iterator<char>(T)),
63 std::istreambuf_iterator<char>());
64}
65
Kostya Serebryany5b266a82015-02-04 19:10:20 +000066void CopyFileToErr(const std::string &Path) {
Kostya Serebryany20e9bcb2015-05-23 01:07:46 +000067 Printf("%s", FileToString(Path).c_str());
Kostya Serebryany5b266a82015-02-04 19:10:20 +000068}
69
Aaron Ballmanef116982015-01-29 16:58:29 +000070void WriteToFile(const Unit &U, const std::string &Path) {
Kostya Serebryanyac25eeb2015-08-12 00:55:09 +000071 // Use raw C interface because this function may be called from a sig handler.
72 FILE *Out = fopen(Path.c_str(), "w");
73 if (!Out) return;
74 fwrite(U.data(), sizeof(U[0]), U.size(), Out);
75 fclose(Out);
Aaron Ballmanef116982015-01-29 16:58:29 +000076}
77
Kostya Serebryany1ac80552015-05-08 21:30:55 +000078void ReadDirToVectorOfUnits(const char *Path, std::vector<Unit> *V,
79 long *Epoch) {
80 long E = Epoch ? *Epoch : 0;
81 for (auto &X : ListFilesInDir(Path, Epoch)) {
82 auto FilePath = DirPlusFile(Path, X);
83 if (Epoch && GetEpoch(FilePath) < E) continue;
84 V->push_back(FileToVector(FilePath));
85 }
Aaron Ballmanef116982015-01-29 16:58:29 +000086}
87
88std::string DirPlusFile(const std::string &DirPath,
89 const std::string &FileName) {
90 return DirPath + "/" + FileName;
91}
92
Kostya Serebryanyca6a2a22015-05-05 21:59:51 +000093void PrintFileAsBase64(const std::string &Path) {
94 std::string Cmd = "base64 -w 0 < " + Path + "; echo";
Kostya Serebryany2da7b842015-05-18 21:34:20 +000095 ExecuteCommand(Cmd);
Kostya Serebryanyca6a2a22015-05-05 21:59:51 +000096}
97
Kostya Serebryany20e9bcb2015-05-23 01:07:46 +000098void Printf(const char *Fmt, ...) {
99 va_list ap;
100 va_start(ap, Fmt);
101 vfprintf(stderr, Fmt, ap);
102 va_end(ap);
103}
104
Aaron Ballmanef116982015-01-29 16:58:29 +0000105} // namespace fuzzer