summaryrefslogtreecommitdiff
path: root/cmds/incident/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cmds/incident/main.cpp')
-rw-r--r--cmds/incident/main.cpp58
1 files changed, 41 insertions, 17 deletions
diff --git a/cmds/incident/main.cpp b/cmds/incident/main.cpp
index dfb4f994b866..6c3d19715c2e 100644
--- a/cmds/incident/main.cpp
+++ b/cmds/incident/main.cpp
@@ -198,6 +198,26 @@ parse_receiver_arg(const string& arg, string* pkg, string* cls)
}
// ================================================================================
+static int
+stream_output(const int read_fd, const int write_fd) {
+ while (true) {
+ uint8_t buf[4096];
+ ssize_t amt = TEMP_FAILURE_RETRY(read(read_fd, buf, sizeof(buf)));
+ if (amt < 0) {
+ break;
+ } else if (amt == 0) {
+ break;
+ }
+
+ ssize_t wamt = TEMP_FAILURE_RETRY(write(write_fd, buf, amt));
+ if (wamt != amt) {
+ return errno;
+ }
+ }
+ return 0;
+}
+
+// ================================================================================
static void
usage(FILE* out)
{
@@ -208,11 +228,13 @@ usage(FILE* out)
fprintf(out, "OPTIONS\n");
fprintf(out, " -l list available sections\n");
fprintf(out, " -p privacy spec, LOCAL, EXPLICIT or AUTOMATIC. Default AUTOMATIC.\n");
+ fprintf(out, " -r REASON human readable description of why the report is taken.\n");
fprintf(out, "\n");
fprintf(out, "and one of these destinations:\n");
fprintf(out, " -b (default) print the report to stdout (in proto format)\n");
fprintf(out, " -d send the report into dropbox\n");
- fprintf(out, " -r REASON human readable description of why the report is taken.\n");
+ fprintf(out, " -u print a full report to stdout for dumpstate to zip as a bug\n");
+ fprintf(out, " report. SECTION is ignored. Should only be called by dumpstate.\n");
fprintf(out, " -s PKG/CLS send broadcast to the broadcast receiver.\n");
fprintf(out, "\n");
fprintf(out, " SECTION the field numbers of the incident report fields to include\n");
@@ -224,14 +246,14 @@ main(int argc, char** argv)
{
Status status;
IncidentReportArgs args;
- enum { DEST_UNSET, DEST_DROPBOX, DEST_STDOUT, DEST_BROADCAST } destination = DEST_UNSET;
+ enum { DEST_UNSET, DEST_DROPBOX, DEST_STDOUT, DEST_BROADCAST, DEST_DUMPSTATE } destination = DEST_UNSET;
int privacyPolicy = PRIVACY_POLICY_AUTOMATIC;
string reason;
string receiverArg;
// Parse the args
int opt;
- while ((opt = getopt(argc, argv, "bhdlp:r:s:")) != -1) {
+ while ((opt = getopt(argc, argv, "bhdlp:r:s:u")) != -1) {
switch (opt) {
case 'h':
usage(stdout);
@@ -253,6 +275,13 @@ main(int argc, char** argv)
}
destination = DEST_DROPBOX;
break;
+ case 'u':
+ if (!(destination == DEST_UNSET || destination == DEST_DUMPSTATE)) {
+ usage(stderr);
+ return 1;
+ }
+ destination = DEST_DUMPSTATE;
+ break;
case 'p':
privacyPolicy = get_privacy_policy(optarg);
break;
@@ -355,21 +384,16 @@ main(int argc, char** argv)
// Wait for the result and print out the data they send.
//IPCThreadState::self()->joinThreadPool();
-
- while (true) {
- uint8_t buf[4096];
- ssize_t amt = TEMP_FAILURE_RETRY(read(fds[0], buf, sizeof(buf)));
- if (amt < 0) {
- break;
- } else if (amt == 0) {
- break;
- }
-
- ssize_t wamt = TEMP_FAILURE_RETRY(write(STDOUT_FILENO, buf, amt));
- if (wamt != amt) {
- return errno;
- }
+ return stream_output(fds[0], STDOUT_FILENO);
+ } else if (destination == DEST_DUMPSTATE) {
+ // Call into the service
+ sp<StatusListener> listener(new StatusListener());
+ status = service->reportIncidentToDumpstate(writeEnd, listener);
+ if (!status.isOk()) {
+ fprintf(stderr, "reportIncident returned \"%s\"\n", status.toString8().string());
+ return 1;
}
+ return stream_output(fds[0], STDOUT_FILENO);
} else {
status = service->reportIncident(args);
if (!status.isOk()) {