12628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme/* 22628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme * Copyright (C) 2016 The Android Open Source Project 32628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme * 42628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme * Licensed under the Apache License, Version 2.0 (the "License"); 52628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme * you may not use this file except in compliance with the License. 62628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme * You may obtain a copy of the License at 72628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme * 82628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme * http://www.apache.org/licenses/LICENSE-2.0 92628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme * 102628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme * Unless required by applicable law or agreed to in writing, software 112628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme * distributed under the License is distributed on an "AS IS" BASIS, 122628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme * See the License for the specific language governing permissions and 142628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme * limitations under the License. 152628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme */ 162628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme 172628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme#include <errno.h> 182628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme#include <stdio.h> 1959f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme#include <stdlib.h> 2059f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme#include <string.h> 212628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme#include <unistd.h> 222628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme 2302b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme#include <string> 2402b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme 2502b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme#include <android-base/file.h> 2602b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme#include <android-base/strings.h> 2702b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme 2859f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme#include "bugreportz.h" 292628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme 30aabfcae816485b39b244ba372c5b2678d2af03beFelipe Lemestatic constexpr char BEGIN_PREFIX[] = "BEGIN:"; 3102b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Lemestatic constexpr char PROGRESS_PREFIX[] = "PROGRESS:"; 3202b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme 3302b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Lemestatic void write_line(const std::string& line, bool show_progress) { 3402b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme if (line.empty()) return; 3502b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme 36aabfcae816485b39b244ba372c5b2678d2af03beFelipe Leme // When not invoked with the -p option, it must skip BEGIN and PROGRESS lines otherwise it 3702b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme // will break adb (which is expecting either OK or FAIL). 38aabfcae816485b39b244ba372c5b2678d2af03beFelipe Leme if (!show_progress && (android::base::StartsWith(line, PROGRESS_PREFIX) || 39aabfcae816485b39b244ba372c5b2678d2af03beFelipe Leme android::base::StartsWith(line, BEGIN_PREFIX))) 40aabfcae816485b39b244ba372c5b2678d2af03beFelipe Leme return; 4102b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme 4202b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme android::base::WriteStringToFd(line, STDOUT_FILENO); 4302b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme} 4402b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme 4502b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Lemeint bugreportz(int s, bool show_progress) { 4602b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme std::string line; 472628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme while (1) { 482628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme char buffer[65536]; 4959f5af0465dcbf275a3653ac23885d12ee7e395dFelipe Leme ssize_t bytes_read = TEMP_FAILURE_RETRY(read(s, buffer, sizeof(buffer))); 502628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme if (bytes_read == 0) { 512628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme break; 522628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme } else if (bytes_read == -1) { 532628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme // EAGAIN really means time out, so change the errno. 542628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme if (errno == EAGAIN) { 552628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme errno = ETIMEDOUT; 562628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme } 571634d841af26421a76ef4c723095786da6d350a4Felipe Leme printf("FAIL:Bugreport read terminated abnormally (%s)\n", strerror(errno)); 582628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme break; 592628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme } 602628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme 6102b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme // Writes line by line. 6202b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme for (int i = 0; i < bytes_read; i++) { 6302b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme char c = buffer[i]; 6402b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme line.append(1, c); 6502b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme if (c == '\n') { 6602b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme write_line(line, show_progress); 6702b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme line.clear(); 682628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme } 6902b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme } 702628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme } 7102b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme // Process final line, in case it didn't finish with newline 7202b7e00c1e1b0bf22997ab7ed913a9451e5b6b8aFelipe Leme write_line(line, show_progress); 732628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme 741634d841af26421a76ef4c723095786da6d350a4Felipe Leme if (close(s) == -1) { 751634d841af26421a76ef4c723095786da6d350a4Felipe Leme fprintf(stderr, "WARNING: error closing socket: %s\n", strerror(errno)); 761634d841af26421a76ef4c723095786da6d350a4Felipe Leme } 77ceeb64281d012cfac99827adbcdb5800b2ce0542Felipe Leme return EXIT_SUCCESS; 782628e9e939fda323fa44c5cb743f4a77b12a312aFelipe Leme} 79