gecko-dev/toolkit/crashreporter/client/crashreporter_unix_common.cpp

139 строки
3.0 KiB
C++

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "crashreporter.h"
#include <algorithm>
#include <dirent.h>
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>
using namespace CrashReporter;
using std::ios_base;
using std::sort;
using std::string;
using std::vector;
struct FileData {
time_t timestamp;
string path;
};
static bool CompareFDTime(const FileData& fd1, const FileData& fd2) {
return fd1.timestamp > fd2.timestamp;
}
void UIPruneSavedDumps(const string& directory) {
DIR* dirfd = opendir(directory.c_str());
if (!dirfd) return;
vector<FileData> dumpfiles;
while (dirent* dir = readdir(dirfd)) {
FileData fd;
fd.path = directory + '/' + dir->d_name;
if (fd.path.size() < 5) continue;
if (fd.path.compare(fd.path.size() - 4, 4, ".dmp") != 0) continue;
struct stat st;
if (stat(fd.path.c_str(), &st)) {
closedir(dirfd);
return;
}
fd.timestamp = st.st_mtime;
dumpfiles.push_back(fd);
}
closedir(dirfd);
sort(dumpfiles.begin(), dumpfiles.end(), CompareFDTime);
while (dumpfiles.size() > kSaveCount) {
// get the path of the oldest file
string path = dumpfiles[dumpfiles.size() - 1].path;
UIDeleteFile(path.c_str());
// s/.dmp/.extra/
path.replace(path.size() - 4, 4, ".extra");
UIDeleteFile(path.c_str());
dumpfiles.pop_back();
}
}
bool UIRunProgram(const string& exename, const vector<string>& args,
bool wait) {
pid_t pid = fork();
if (pid == -1) {
return false;
} else if (pid == 0) {
// Child
size_t argvLen = args.size() + 2;
vector<char*> argv(argvLen);
argv[0] = const_cast<char*>(exename.c_str());
for (size_t i = 0; i < args.size(); i++) {
argv[i + 1] = const_cast<char*>(args[i].c_str());
}
argv[argvLen - 1] = nullptr;
// Run the program
int rv = execv(exename.c_str(), argv.data());
if (rv == -1) {
exit(EXIT_FAILURE);
}
} else {
// Parent
if (wait) {
waitpid(pid, nullptr, 0);
}
}
return true;
}
bool UIEnsurePathExists(const string& path) {
int ret = mkdir(path.c_str(), S_IRWXU);
int e = errno;
if (ret == -1 && e != EEXIST) return false;
return true;
}
bool UIFileExists(const string& path) {
struct stat sb;
int ret = stat(path.c_str(), &sb);
if (ret == -1 || !(sb.st_mode & S_IFREG)) return false;
return true;
}
bool UIDeleteFile(const string& file) { return (unlink(file.c_str()) != -1); }
std::ifstream* UIOpenRead(const string& filename, ios_base::openmode mode) {
return new std::ifstream(filename.c_str(), mode);
}
std::ofstream* UIOpenWrite(const string& filename, ios_base::openmode mode) {
return new std::ofstream(filename.c_str(), mode);
}
string UIGetEnv(const string& name) {
const char* var = getenv(name.c_str());
if (var && *var) {
return var;
}
return "";
}