Path: blob/main/contrib/llvm-project/compiler-rt/lib/fuzzer/FuzzerIOPosix.cpp
35262 views
//===- FuzzerIOPosix.cpp - IO utils for Posix. ----------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7// IO functions implementation using Posix API.8//===----------------------------------------------------------------------===//9#include "FuzzerPlatform.h"10#if LIBFUZZER_POSIX || LIBFUZZER_FUCHSIA1112#include "FuzzerExtFunctions.h"13#include "FuzzerIO.h"14#include <cstdarg>15#include <cstdio>16#include <dirent.h>17#include <fstream>18#include <iterator>19#include <libgen.h>20#include <sys/stat.h>21#include <sys/types.h>22#include <unistd.h>2324namespace fuzzer {2526bool IsFile(const std::string &Path) {27struct stat St;28if (stat(Path.c_str(), &St))29return false;30return S_ISREG(St.st_mode);31}3233bool IsDirectory(const std::string &Path) {34struct stat St;35if (stat(Path.c_str(), &St))36return false;37return S_ISDIR(St.st_mode);38}3940size_t FileSize(const std::string &Path) {41struct stat St;42if (stat(Path.c_str(), &St))43return 0;44return St.st_size;45}4647std::string Basename(const std::string &Path) {48size_t Pos = Path.rfind(GetSeparator());49if (Pos == std::string::npos) return Path;50assert(Pos < Path.size());51return Path.substr(Pos + 1);52}5354void ListFilesInDirRecursive(const std::string &Dir, long *Epoch,55std::vector<std::string> *V, bool TopDir) {56auto E = GetEpoch(Dir);57if (Epoch)58if (E && *Epoch >= E) return;5960DIR *D = opendir(Dir.c_str());61if (!D) {62Printf("%s: %s; exiting\n", strerror(errno), Dir.c_str());63exit(1);64}65while (auto E = readdir(D)) {66std::string Path = DirPlusFile(Dir, E->d_name);67if (E->d_type == DT_REG || E->d_type == DT_LNK ||68(E->d_type == DT_UNKNOWN && IsFile(Path)))69V->push_back(Path);70else if ((E->d_type == DT_DIR ||71(E->d_type == DT_UNKNOWN && IsDirectory(Path))) &&72*E->d_name != '.')73ListFilesInDirRecursive(Path, Epoch, V, false);74}75closedir(D);76if (Epoch && TopDir)77*Epoch = E;78}7980void IterateDirRecursive(const std::string &Dir,81void (*DirPreCallback)(const std::string &Dir),82void (*DirPostCallback)(const std::string &Dir),83void (*FileCallback)(const std::string &Dir)) {84DirPreCallback(Dir);85DIR *D = opendir(Dir.c_str());86if (!D) return;87while (auto E = readdir(D)) {88std::string Path = DirPlusFile(Dir, E->d_name);89if (E->d_type == DT_REG || E->d_type == DT_LNK ||90(E->d_type == DT_UNKNOWN && IsFile(Path)))91FileCallback(Path);92else if ((E->d_type == DT_DIR ||93(E->d_type == DT_UNKNOWN && IsDirectory(Path))) &&94*E->d_name != '.')95IterateDirRecursive(Path, DirPreCallback, DirPostCallback, FileCallback);96}97closedir(D);98DirPostCallback(Dir);99}100101char GetSeparator() {102return '/';103}104105bool IsSeparator(char C) {106return C == '/';107}108109FILE* OpenFile(int Fd, const char* Mode) {110return fdopen(Fd, Mode);111}112113int CloseFile(int fd) {114return close(fd);115}116117int DuplicateFile(int Fd) {118return dup(Fd);119}120121void RemoveFile(const std::string &Path) {122unlink(Path.c_str());123}124125void RenameFile(const std::string &OldPath, const std::string &NewPath) {126rename(OldPath.c_str(), NewPath.c_str());127}128129intptr_t GetHandleFromFd(int fd) {130return static_cast<intptr_t>(fd);131}132133std::string DirName(const std::string &FileName) {134char *Tmp = new char[FileName.size() + 1];135memcpy(Tmp, FileName.c_str(), FileName.size() + 1);136std::string Res = dirname(Tmp);137delete [] Tmp;138return Res;139}140141std::string TmpDir() {142if (auto Env = getenv("TMPDIR"))143return Env;144return "/tmp";145}146147bool IsInterestingCoverageFile(const std::string &FileName) {148if (FileName.find("compiler-rt/lib/") != std::string::npos)149return false; // sanitizer internal.150if (FileName.find("/usr/lib/") != std::string::npos)151return false;152if (FileName.find("/usr/include/") != std::string::npos)153return false;154if (FileName == "<null>")155return false;156return true;157}158159void RawPrint(const char *Str) {160(void)write(2, Str, strlen(Str));161}162163void MkDir(const std::string &Path) {164mkdir(Path.c_str(), 0700);165}166167void RmDir(const std::string &Path) {168rmdir(Path.c_str());169}170171const std::string &getDevNull() {172static const std::string devNull = "/dev/null";173return devNull;174}175176} // namespace fuzzer177178#endif // LIBFUZZER_POSIX179180181