Streaming bugreport content to stdout 1/2

Add a -s option to bugreportz to support streaming data.

Bug: 162910469
Test: adb bugreport --stream > test.txt
Test: adb shell bugreportz -s > test2.txt
Test: atest dumpstate_test
Test: atest bugreportz_test

Change-Id: I33d68bf742c92a7359a925838827a0033ee68658
This commit is contained in:
Dieter Hsu 2020-09-29 15:23:33 +08:00
parent 270193009f
commit 031c957e55
3 changed files with 52 additions and 11 deletions

View file

@ -14,6 +14,10 @@
* limitations under the License.
*/
#include "bugreportz.h"
#include <android-base/file.h>
#include <android-base/strings.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@ -22,11 +26,6 @@
#include <string>
#include <android-base/file.h>
#include <android-base/strings.h>
#include "bugreportz.h"
static constexpr char BEGIN_PREFIX[] = "BEGIN:";
static constexpr char PROGRESS_PREFIX[] = "PROGRESS:";
@ -70,6 +69,30 @@ int bugreportz(int s, bool show_progress) {
}
// Process final line, in case it didn't finish with newline
write_line(line, show_progress);
return EXIT_SUCCESS;
}
int bugreportz_stream(int s) {
while (1) {
char buffer[65536];
ssize_t bytes_read = TEMP_FAILURE_RETRY(read(s, buffer, sizeof(buffer)));
if (bytes_read == 0) {
break;
} else if (bytes_read == -1) {
// EAGAIN really means time out, so change the errno.
if (errno == EAGAIN) {
errno = ETIMEDOUT;
}
printf("FAIL:Bugreport read terminated abnormally (%s)\n", strerror(errno));
return EXIT_FAILURE;
}
if (!android::base::WriteFully(android::base::borrowed_fd(STDOUT_FILENO), buffer,
bytes_read)) {
printf("Failed to write data to stdout: trying to send %zd bytes (%s)\n", bytes_read,
strerror(errno));
return EXIT_FAILURE;
}
}
return EXIT_SUCCESS;
}

View file

@ -19,4 +19,8 @@
// Ownership of the socket is not transferred.
int bugreportz(int s, bool show_progress);
// Calls dumpstate using the given socket and write the file content to stdout
// instead of file location. Ownership of the socket is not transferred.
int bugreportz_stream(int s);
#endif // BUGREPORTZ_H

View file

@ -26,13 +26,14 @@
#include "bugreportz.h"
static constexpr char VERSION[] = "1.1";
static constexpr char VERSION[] = "1.2";
static void show_usage() {
fprintf(stderr,
"usage: bugreportz [-hpv]\n"
"usage: bugreportz [-hpsv]\n"
" -h: to display this help message\n"
" -p: display progress\n"
" -s: stream content to standard output\n"
" -v: to display the version\n"
" or no arguments to generate a zipped bugreport\n");
}
@ -43,10 +44,11 @@ static void show_version() {
int main(int argc, char* argv[]) {
bool show_progress = false;
bool stream_data = false;
if (argc > 1) {
/* parse arguments */
int c;
while ((c = getopt(argc, argv, "hpv")) != -1) {
while ((c = getopt(argc, argv, "hpsv")) != -1) {
switch (c) {
case 'h':
show_usage();
@ -54,6 +56,9 @@ int main(int argc, char* argv[]) {
case 'p':
show_progress = true;
break;
case 's':
stream_data = true;
break;
case 'v':
show_version();
return EXIT_SUCCESS;
@ -75,7 +80,11 @@ int main(int argc, char* argv[]) {
// should be reused instead.
// Start the dumpstatez service.
property_set("ctl.start", "dumpstatez");
if (stream_data) {
property_set("ctl.start", "dumpstate");
} else {
property_set("ctl.start", "dumpstatez");
}
// Socket will not be available until service starts.
int s = -1;
@ -103,7 +112,12 @@ int main(int argc, char* argv[]) {
strerror(errno));
}
int ret = bugreportz(s, show_progress);
int ret;
if (stream_data) {
ret = bugreportz_stream(s);
} else {
ret = bugreportz(s, show_progress);
}
if (close(s) == -1) {
fprintf(stderr, "WARNING: error closing socket: %s\n", strerror(errno));