mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 14:06:33 +00:00
crashpad_database_util: Accept --new-report=- to read a new report from
standard input. R=rsesek@chromium.org Review URL: https://codereview.chromium.org/1023943003 .
This commit is contained in:
parent
29eeec3d56
commit
124ace19bd
@ -105,8 +105,9 @@ numeric +time_t+ value, or the special string +"never"+.
|
||||
See also *--show-last-upload-attempt-time*.
|
||||
|
||||
*--new-report*='PATH'::
|
||||
Submit a new report located at 'PATH' to the database. The new report will be in
|
||||
the “pending” state. The UUID assigned to the new report will be printed. This
|
||||
Submit a new report located at 'PATH' to the database. If 'PATH' is +"-"+, the
|
||||
new report will be read from standard input. The new report will be in the
|
||||
“pending” state. The UUID assigned to the new report will be printed. This
|
||||
option may appear multiple times.
|
||||
|
||||
*--utc*::
|
||||
|
@ -58,7 +58,7 @@ void Usage(const base::FilePath& me) {
|
||||
" --set-uploads-enabled=BOOL enable or disable uploads\n"
|
||||
" --set-last-upload-attempt-time=TIME\n"
|
||||
" set the last-upload-attempt time to TIME\n"
|
||||
" --new-report=PATH submit a new report at PATH\n"
|
||||
" --new-report=PATH submit a new report at PATH, or - for stdin\n"
|
||||
" --utc show and set UTC times instead of local\n"
|
||||
" --help display this help and exit\n"
|
||||
" --version output version information and exit\n",
|
||||
@ -527,9 +527,19 @@ int DatabaseUtilMain(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
for (const base::FilePath new_report_path : options.new_report_paths) {
|
||||
FileReader file_reader;
|
||||
if (!file_reader.Open(new_report_path)) {
|
||||
return EXIT_FAILURE;
|
||||
scoped_ptr<FileReaderInterface> file_reader;
|
||||
|
||||
bool is_stdin = false;
|
||||
if (new_report_path.value() == FILE_PATH_LITERAL("-")) {
|
||||
is_stdin = true;
|
||||
file_reader.reset(new WeakStdioFileReader(stdin));
|
||||
} else {
|
||||
scoped_ptr<FileReader> file_path_reader(new FileReader());
|
||||
if (!file_path_reader->Open(new_report_path)) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
file_reader = file_path_reader.Pass();
|
||||
}
|
||||
|
||||
CrashReportDatabase::NewReport* new_report;
|
||||
@ -544,14 +554,16 @@ int DatabaseUtilMain(int argc, char* argv[]) {
|
||||
|
||||
char buf[4096];
|
||||
ssize_t read_result;
|
||||
while ((read_result = file_reader.Read(buf, sizeof(buf))) > 0) {
|
||||
if (!LoggingWriteFile(new_report->handle, buf, read_result)) {
|
||||
do {
|
||||
read_result = file_reader->Read(buf, sizeof(buf));
|
||||
if (read_result < 0) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
if (read_result < 0) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (read_result > 0 &&
|
||||
!LoggingWriteFile(new_report->handle, buf, read_result)) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
} while (read_result == sizeof(buf));
|
||||
|
||||
call_error_writing_crash_report.Disarm();
|
||||
|
||||
@ -561,6 +573,13 @@ int DatabaseUtilMain(int argc, char* argv[]) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
file_reader.reset();
|
||||
if (is_stdin) {
|
||||
if (fclose(stdin) == EOF) {
|
||||
STDIO_PLOG(ERROR) << "fclose";
|
||||
}
|
||||
}
|
||||
|
||||
const char* prefix = (show_operations > 1) ? "New report ID: " : "";
|
||||
printf("%s%s\n", prefix, uuid.ToString().c_str());
|
||||
}
|
||||
|
@ -26,6 +26,27 @@
|
||||
#include "util/win/scoped_handle.h"
|
||||
#endif
|
||||
|
||||
//! \file
|
||||
|
||||
#if defined(OS_POSIX) || DOXYGEN
|
||||
|
||||
//! \brief A `PLOG()` macro usable for standard input/output error conditions.
|
||||
//!
|
||||
//! The `PLOG()` macro uses `errno` on POSIX and is appropriate to report
|
||||
//! errors from standard input/output functions. On Windows, `PLOG()` uses
|
||||
//! `GetLastError()`, and cannot be used to report errors from standard
|
||||
//! input/output functions. This macro uses `PLOG()` when appropriate for
|
||||
//! standard I/O functions, and `LOG()` otherwise.
|
||||
#define STDIO_PLOG(x) PLOG(x)
|
||||
|
||||
#else
|
||||
|
||||
#define STDIO_PLOG(x) LOG(x)
|
||||
#define fseeko(file, offset, whence) _fseeki64(file, offset, whence)
|
||||
#define ftello(file) _ftelli64(file)
|
||||
|
||||
#endif
|
||||
|
||||
namespace base {
|
||||
class FilePath;
|
||||
} // namespace base
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/numerics/safe_conversions.h"
|
||||
#include "build/build_config.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
@ -97,4 +98,39 @@ FileOffset FileReader::Seek(FileOffset offset, int whence) {
|
||||
return weak_file_handle_file_reader_.Seek(offset, whence);
|
||||
}
|
||||
|
||||
WeakStdioFileReader::WeakStdioFileReader(FILE* file)
|
||||
: file_(file) {
|
||||
}
|
||||
|
||||
WeakStdioFileReader::~WeakStdioFileReader() {
|
||||
}
|
||||
|
||||
ssize_t WeakStdioFileReader::Read(void* data, size_t size) {
|
||||
DCHECK(file_);
|
||||
|
||||
size_t rv = fread(data, 1, size, file_);
|
||||
if (rv < size && ferror(file_)) {
|
||||
STDIO_PLOG(ERROR) << "fread";
|
||||
return -1;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
FileOffset WeakStdioFileReader::Seek(FileOffset offset, int whence) {
|
||||
DCHECK(file_);
|
||||
if (fseeko(file_, offset, whence) == -1) {
|
||||
STDIO_PLOG(ERROR) << "fseeko";
|
||||
return -1;
|
||||
}
|
||||
|
||||
FileOffset new_offset = ftello(file_);
|
||||
if (new_offset == -1) {
|
||||
STDIO_PLOG(ERROR) << "ftello";
|
||||
return -1;
|
||||
}
|
||||
|
||||
return new_offset;
|
||||
}
|
||||
|
||||
} // namespace crashpad
|
||||
|
@ -15,6 +15,7 @@
|
||||
#ifndef CRASHPAD_UTIL_FILE_FILE_READER_H_
|
||||
#define CRASHPAD_UTIL_FILE_FILE_READER_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
@ -28,6 +29,8 @@ namespace crashpad {
|
||||
//! semantics matching the underlying platform (POSIX or Windows).
|
||||
class FileReaderInterface : public virtual FileSeekerInterface {
|
||||
public:
|
||||
virtual ~FileReaderInterface() {}
|
||||
|
||||
//! \brief Wraps ReadFile(), or provides an implementation with identical
|
||||
//! semantics.
|
||||
//!
|
||||
@ -44,9 +47,6 @@ class FileReaderInterface : public virtual FileSeekerInterface {
|
||||
//! \return `true` if the operation succeeded, `false` if it failed, with an
|
||||
//! error message logged. Short reads are treated as failures.
|
||||
bool ReadExactly(void* data, size_t size);
|
||||
|
||||
protected:
|
||||
~FileReaderInterface() {}
|
||||
};
|
||||
|
||||
//! \brief A file reader backed by a FileHandle.
|
||||
@ -66,7 +66,7 @@ class FileReaderInterface : public virtual FileSeekerInterface {
|
||||
class WeakFileHandleFileReader : public FileReaderInterface {
|
||||
public:
|
||||
explicit WeakFileHandleFileReader(FileHandle file_handle);
|
||||
~WeakFileHandleFileReader();
|
||||
~WeakFileHandleFileReader() override;
|
||||
|
||||
// FileReaderInterface:
|
||||
ssize_t Read(void* data, size_t size) override;
|
||||
@ -99,7 +99,7 @@ class WeakFileHandleFileReader : public FileReaderInterface {
|
||||
class FileReader : public FileReaderInterface {
|
||||
public:
|
||||
FileReader();
|
||||
~FileReader();
|
||||
~FileReader() override;
|
||||
|
||||
// FileReaderInterface:
|
||||
|
||||
@ -142,6 +142,40 @@ class FileReader : public FileReaderInterface {
|
||||
DISALLOW_COPY_AND_ASSIGN(FileReader);
|
||||
};
|
||||
|
||||
//! \brief A file reader backed by a standard input/output `FILE*`.
|
||||
//!
|
||||
//! This class accepts an already-open `FILE*`. It is not responsible for
|
||||
//! opening or closing this `FILE*`. Users of this class must ensure that the
|
||||
//! `FILE*` is closed appropriately elsewhere. Objects of this class may be used
|
||||
//! to read from `FILE*` objects not associated with filesystem-based files,
|
||||
//! although special attention should be paid to the Seek() method, which may
|
||||
//! not function on `FILE*` objects that do not refer to disk-based files.
|
||||
//!
|
||||
//! This class is expected to be used when other code is responsible for
|
||||
//! opening `FILE*` objects and already provides `FILE*` objects. A good use
|
||||
//! would be a WeakStdioFileReader for `stdin`.
|
||||
class WeakStdioFileReader : public FileReaderInterface {
|
||||
public:
|
||||
explicit WeakStdioFileReader(FILE* file);
|
||||
~WeakStdioFileReader() override;
|
||||
|
||||
// FileReaderInterface:
|
||||
ssize_t Read(void* data, size_t size) override;
|
||||
|
||||
// FileSeekerInterface:
|
||||
|
||||
//! \copydoc FileReaderInterface::Seek()
|
||||
//!
|
||||
//! \note This method is only guaranteed to function on `FILE*` objects
|
||||
//! referring to disk-based files.
|
||||
FileOffset Seek(FileOffset offset, int whence) override;
|
||||
|
||||
private:
|
||||
FILE* file_; // weak
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WeakStdioFileReader);
|
||||
};
|
||||
|
||||
} // namespace crashpad
|
||||
|
||||
#endif // CRASHPAD_UTIL_FILE_FILE_READER_H_
|
||||
|
@ -44,6 +44,8 @@ struct WritableIoVec {
|
||||
//! semantics matching the underlying platform (POSIX or Windows).
|
||||
class FileWriterInterface : public virtual FileSeekerInterface {
|
||||
public:
|
||||
virtual ~FileWriterInterface() {}
|
||||
|
||||
//! \brief Wraps LoggingWriteFile(), or provides an implementation with
|
||||
//! identical semantics.
|
||||
//!
|
||||
@ -61,9 +63,6 @@ class FileWriterInterface : public virtual FileSeekerInterface {
|
||||
//!
|
||||
//! \note The contents of \a iovecs are undefined when this method returns.
|
||||
virtual bool WriteIoVec(std::vector<WritableIoVec>* iovecs) = 0;
|
||||
|
||||
protected:
|
||||
~FileWriterInterface() {}
|
||||
};
|
||||
|
||||
//! \brief A file writer backed by a FileHandle.
|
||||
@ -83,7 +82,7 @@ class FileWriterInterface : public virtual FileSeekerInterface {
|
||||
class WeakFileHandleFileWriter : public FileWriterInterface {
|
||||
public:
|
||||
explicit WeakFileHandleFileWriter(FileHandle file_handle);
|
||||
~WeakFileHandleFileWriter();
|
||||
~WeakFileHandleFileWriter() override;
|
||||
|
||||
// FileWriterInterface:
|
||||
bool Write(const void* data, size_t size) override;
|
||||
@ -117,7 +116,7 @@ class WeakFileHandleFileWriter : public FileWriterInterface {
|
||||
class FileWriter : public FileWriterInterface {
|
||||
public:
|
||||
FileWriter();
|
||||
~FileWriter();
|
||||
~FileWriter() override;
|
||||
|
||||
// FileWriterInterface:
|
||||
|
||||
|
@ -36,7 +36,7 @@ namespace crashpad {
|
||||
class StringFile : public FileReaderInterface, public FileWriterInterface {
|
||||
public:
|
||||
StringFile();
|
||||
~StringFile();
|
||||
~StringFile() override;
|
||||
|
||||
//! \brief Returns a string containing the virtual file’s contents.
|
||||
const std::string& string() const { return string_; }
|
||||
|
Loading…
x
Reference in New Issue
Block a user