fune/toolkit/crashreporter/client/crashreporter_unix_common.cpp
Gabriele Svelto a985338445 Bug 1357688 - Clean up and document the crash reporter environment variables; r=ted.mielczarek
This cleans up the way the crash reporter client invokes the minidump analyzer
by removing the extra command-line parameter and replacing it with an
environment variable. Since I was at it I've also cleaned up other uses of env
variables in the code and added documentation for all of them.

MozReview-Commit-ID: ATkgsI3L2Md

--HG--
extra : source : 05a762d6cb5e5fd9856743b4db38287d7c58a487
2018-02-26 15:00:58 +01:00

171 lines
3.3 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::string;
using std::vector;
using std::sort;
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, bool binary)
{
std::ios_base::openmode mode = std::ios::in;
if (binary) {
mode = mode | std::ios::binary;
}
return new std::ifstream(filename.c_str(), mode);
}
std::ofstream* UIOpenWrite(const string& filename,
bool append, // append=false
bool binary) // binary=false
{
std::ios_base::openmode mode = std::ios::out;
if (append) {
mode = mode | std::ios::app;
}
if (binary) {
mode = mode | std::ios::binary;
}
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 "";
}