зеркало из https://github.com/mozilla/gecko-dev.git
139 строки
3.0 KiB
C++
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 "";
|
|
}
|