blob: 258b36721b1031b18e2be541ba680244c486c8fd [file] [log] [blame]
Christopher Ferris9b73bf02015-01-20 19:18:59 -08001/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Felipe Leme3b650732016-08-05 19:29:29 +000017#include <errno.h>
Christopher Ferris9b73bf02015-01-20 19:18:59 -080018#include <stdio.h>
Felipe Leme3b650732016-08-05 19:29:29 +000019#include <sys/socket.h>
20#include <sys/types.h>
21#include <unistd.h>
Christopher Ferris9b73bf02015-01-20 19:18:59 -080022
Felipe Leme3b650732016-08-05 19:29:29 +000023#include <cutils/properties.h>
24#include <cutils/sockets.h>
25
26// This program will trigger the dumpstate service to start a call to
27// dumpstate, then connect to the dumpstate local client to read the
28// output. All of the dumpstate output is written to stdout, including
29// any errors encountered while reading/writing the output.
Elliott Hughes1febe132020-06-09 12:25:15 -070030int main(int argc, char* /*argv*/[]) {
Felipe Leme3b650732016-08-05 19:29:29 +000031 fprintf(stderr, "=============================================================================\n");
Elliott Hughes1febe132020-06-09 12:25:15 -070032 fprintf(stderr, "WARNING: Flat (text file, non-zipped) bugreports are deprecated.\n");
33 fprintf(stderr, "WARNING: Please generate zipped bugreports instead.\n");
34 fprintf(stderr, "WARNING: On the host use: adb bugreport filename.zip\n");
35 fprintf(stderr, "WARNING: On the device use: bugreportz filename.zip\n");
Felipe Leme3b650732016-08-05 19:29:29 +000036 fprintf(stderr, "=============================================================================\n\n\n");
37
Elliott Hughes1febe132020-06-09 12:25:15 -070038 if (argc != 1) {
39 fprintf(stderr, "usage: bugreport\n");
40 exit(1);
41 }
42
Felipe Leme3b650732016-08-05 19:29:29 +000043 // Start the dumpstate service.
44 property_set("ctl.start", "dumpstate");
45
46 // Socket will not be available until service starts.
Stephen Hines6896f062019-05-09 13:03:40 -070047 int s = -1;
Felipe Leme3b650732016-08-05 19:29:29 +000048 for (int i = 0; i < 20; i++) {
49 s = socket_local_client("dumpstate", ANDROID_SOCKET_NAMESPACE_RESERVED,
50 SOCK_STREAM);
51 if (s >= 0)
52 break;
53 // Try again in 1 second.
54 sleep(1);
55 }
56
57 if (s == -1) {
58 printf("Failed to connect to dumpstate service: %s\n", strerror(errno));
59 return 1;
60 }
61
62 // Set a timeout so that if nothing is read in 3 minutes, we'll stop
63 // reading and quit. No timeout in dumpstate is longer than 60 seconds,
64 // so this gives lots of leeway in case of unforeseen time outs.
65 struct timeval tv;
66 tv.tv_sec = 3 * 60;
67 tv.tv_usec = 0;
68 if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) {
69 printf("WARNING: Cannot set socket timeout: %s\n", strerror(errno));
70 }
71
72 while (1) {
73 char buffer[65536];
74 ssize_t bytes_read = TEMP_FAILURE_RETRY(read(s, buffer, sizeof(buffer)));
75 if (bytes_read == 0) {
76 break;
77 } else if (bytes_read == -1) {
78 // EAGAIN really means time out, so change the errno.
79 if (errno == EAGAIN) {
80 errno = ETIMEDOUT;
81 }
82 printf("\nBugreport read terminated abnormally (%s).\n", strerror(errno));
83 break;
84 }
85
86 ssize_t bytes_to_send = bytes_read;
87 ssize_t bytes_written;
88 do {
89 bytes_written = TEMP_FAILURE_RETRY(write(STDOUT_FILENO,
90 buffer + bytes_read - bytes_to_send,
91 bytes_to_send));
92 if (bytes_written == -1) {
93 printf("Failed to write data to stdout: read %zd, trying to send %zd (%s)\n",
94 bytes_read, bytes_to_send, strerror(errno));
95 return 1;
96 }
97 bytes_to_send -= bytes_written;
98 } while (bytes_written != 0 && bytes_to_send > 0);
99 }
100
101 close(s);
102 return 0;
Christopher Ferris9b73bf02015-01-20 19:18:59 -0800103}