Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 45d7690c authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fixed buffering issues."

parents e685bb48 8f00ed03
Loading
Loading
Loading
Loading
+60 −60
Original line number Original line Diff line number Diff line
@@ -602,7 +602,7 @@ static int dump_stat_from_fd(const char *title __unused, const char *path, int f
        path += sizeof(mmcblk0) - 1;
        path += sizeof(mmcblk0) - 1;
    }
    }


    printf("%s: %s\n", path, buffer);
    dprintf(STDOUT_FILENO, "%s: %s\n", path, buffer);
    free(buffer);
    free(buffer);


    if (fields[__STAT_IO_TICKS]) {
    if (fields[__STAT_IO_TICKS]) {
@@ -639,10 +639,10 @@ static int dump_stat_from_fd(const char *title __unused, const char *path, int f
                                 / fields[__STAT_IO_TICKS];
                                 / fields[__STAT_IO_TICKS];


        if (!write_perf && !write_ios) {
        if (!write_perf && !write_ios) {
            printf("%s: perf(ios) rd: %luKB/s(%lu/s) q: %u\n",
            dprintf(STDOUT_FILENO, "%s: perf(ios) rd: %luKB/s(%lu/s) q: %u\n", path, read_perf,
                   path, read_perf, read_ios, queue);
                    read_ios, queue);
        } else {
        } else {
            printf("%s: perf(ios) rd: %luKB/s(%lu/s) wr: %luKB/s(%lu/s) q: %u\n",
            dprintf(STDOUT_FILENO, "%s: perf(ios) rd: %luKB/s(%lu/s) wr: %luKB/s(%lu/s) q: %u\n",
                    path, read_perf, read_ios, write_perf, write_ios, queue);
                    path, read_perf, read_ios, write_perf, write_ios, queue);
        }
        }


@@ -673,27 +673,27 @@ void Dumpstate::PrintHeader() const {
    network = android::base::GetProperty("gsm.operator.alpha", "(unknown)");
    network = android::base::GetProperty("gsm.operator.alpha", "(unknown)");
    strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&now_));
    strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&now_));


    printf("========================================================\n");
    dprintf(STDOUT_FILENO, "========================================================\n");
    printf("== dumpstate: %s\n", date);
    dprintf(STDOUT_FILENO, "== dumpstate: %s\n", date);
    printf("========================================================\n");
    dprintf(STDOUT_FILENO, "========================================================\n");


    printf("\n");
    dprintf(STDOUT_FILENO, "\n");
    printf("Build: %s\n", build.c_str());
    dprintf(STDOUT_FILENO, "Build: %s\n", build.c_str());
    // NOTE: fingerprint entry format is important for other tools.
    // NOTE: fingerprint entry format is important for other tools.
    printf("Build fingerprint: '%s'\n", fingerprint.c_str());
    dprintf(STDOUT_FILENO, "Build fingerprint: '%s'\n", fingerprint.c_str());
    printf("Bootloader: %s\n", bootloader.c_str());
    dprintf(STDOUT_FILENO, "Bootloader: %s\n", bootloader.c_str());
    printf("Radio: %s\n", radio.c_str());
    dprintf(STDOUT_FILENO, "Radio: %s\n", radio.c_str());
    printf("Network: %s\n", network.c_str());
    dprintf(STDOUT_FILENO, "Network: %s\n", network.c_str());


    printf("Kernel: ");
    dprintf(STDOUT_FILENO, "Kernel: ");
    fflush(stdout);
    fsync(STDOUT_FILENO);
    DumpFileToFd(STDOUT_FILENO, "", "/proc/version");
    DumpFileToFd(STDOUT_FILENO, "", "/proc/version");
    printf("Command line: %s\n", strtok(cmdline_buf, "\n"));
    dprintf(STDOUT_FILENO, "Command line: %s\n", strtok(cmdline_buf, "\n"));
    printf("Bugreport format version: %s\n", version_.c_str());
    dprintf(STDOUT_FILENO, "Bugreport format version: %s\n", version_.c_str());
    printf("Dumpstate info: id=%d pid=%d dry_run=%d args=%s extra_options=%s\n", id_, pid_,
    dprintf(STDOUT_FILENO, "Dumpstate info: id=%d pid=%d dry_run=%d args=%s extra_options=%s\n",
           PropertiesHelper::IsDryRun(), args_.c_str(), extra_options_.c_str());
            id_, pid_, PropertiesHelper::IsDryRun(), args_.c_str(), extra_options_.c_str());
    printf("\n");
    dprintf(STDOUT_FILENO, "\n");
    fflush(stdout);
    fsync(STDOUT_FILENO);
}
}


// List of file extensions that can cause a zip file attachment to be rejected by some email
// List of file extensions that can cause a zip file attachment to be rejected by some email
@@ -857,13 +857,13 @@ static void AddAnrTraceFiles() {
           dump_traces_dir.c_str(), anr_traces_dir.c_str(), already_dumped);
           dump_traces_dir.c_str(), anr_traces_dir.c_str(), already_dumped);


    if (anr_traces_path.empty()) {
    if (anr_traces_path.empty()) {
        printf("*** NO VM TRACES FILE DEFINED (dalvik.vm.stack-trace-file)\n\n");
        dprintf(STDOUT_FILENO, "*** NO VM TRACES FILE DEFINED (dalvik.vm.stack-trace-file)\n\n");
    } else {
    } else {
        int fd = TEMP_FAILURE_RETRY(
        int fd = TEMP_FAILURE_RETRY(
            open(anr_traces_path.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK));
            open(anr_traces_path.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK));
        if (fd < 0) {
        if (fd < 0) {
            printf("*** NO ANR VM TRACES FILE (%s): %s\n\n", anr_traces_path.c_str(),
            dprintf(STDOUT_FILENO, "*** NO ANR VM TRACES FILE (%s): %s\n\n",
                   strerror(errno));
                    anr_traces_path.c_str(), strerror(errno));
        } else {
        } else {
            if (add_to_zip) {
            if (add_to_zip) {
                if (!already_dumped) {
                if (!already_dumped) {
@@ -1003,7 +1003,7 @@ static void dumpstate() {
        }
        }
    }
    }
    if (!dumped) {
    if (!dumped) {
        printf("*** NO TOMBSTONES to dump in %s\n\n", TOMBSTONE_DIR);
        dprintf(STDOUT_FILENO, "*** NO TOMBSTONES to dump in %s\n\n", TOMBSTONE_DIR);
    }
    }


    DumpFile("NETWORK DEV INFO", "/proc/net/dev");
    DumpFile("NETWORK DEV INFO", "/proc/net/dev");
@@ -1076,18 +1076,18 @@ static void dumpstate() {


    RunCommand("LAST RADIO LOG", {"parse_radio_log", "/proc/last_radio_log"});
    RunCommand("LAST RADIO LOG", {"parse_radio_log", "/proc/last_radio_log"});


    printf("------ BACKLIGHTS ------\n");
    dprintf(STDOUT_FILENO, "------ BACKLIGHTS ------\n");
    printf("LCD brightness=");
    dprintf(STDOUT_FILENO, "LCD brightness=");
    DumpFile("", "/sys/class/leds/lcd-backlight/brightness");
    DumpFile("", "/sys/class/leds/lcd-backlight/brightness");
    printf("Button brightness=");
    dprintf(STDOUT_FILENO, "Button brightness=");
    DumpFile("", "/sys/class/leds/button-backlight/brightness");
    DumpFile("", "/sys/class/leds/button-backlight/brightness");
    printf("Keyboard brightness=");
    dprintf(STDOUT_FILENO, "Keyboard brightness=");
    DumpFile("", "/sys/class/leds/keyboard-backlight/brightness");
    DumpFile("", "/sys/class/leds/keyboard-backlight/brightness");
    printf("ALS mode=");
    dprintf(STDOUT_FILENO, "ALS mode=");
    DumpFile("", "/sys/class/leds/lcd-backlight/als");
    DumpFile("", "/sys/class/leds/lcd-backlight/als");
    printf("LCD driver registers:\n");
    dprintf(STDOUT_FILENO, "LCD driver registers:\n");
    DumpFile("", "/sys/class/leds/lcd-backlight/registers");
    DumpFile("", "/sys/class/leds/lcd-backlight/registers");
    printf("\n");
    dprintf(STDOUT_FILENO, "\n");


    /* Binder state is expensive to look at as it uses a lot of memory. */
    /* Binder state is expensive to look at as it uses a lot of memory. */
    DumpFile("BINDER FAILED TRANSACTION LOG", "/sys/kernel/debug/binder/failed_transaction_log");
    DumpFile("BINDER FAILED TRANSACTION LOG", "/sys/kernel/debug/binder/failed_transaction_log");
@@ -1112,16 +1112,16 @@ static void dumpstate() {
        RunCommand("DUMP VENDOR RIL LOGS", {"vril-dump"}, options.Build());
        RunCommand("DUMP VENDOR RIL LOGS", {"vril-dump"}, options.Build());
    }
    }


    printf("========================================================\n");
    dprintf(STDOUT_FILENO, "========================================================\n");
    printf("== Android Framework Services\n");
    dprintf(STDOUT_FILENO, "== Android Framework Services\n");
    printf("========================================================\n");
    dprintf(STDOUT_FILENO, "========================================================\n");


    RunDumpsys("DUMPSYS", {"--skip", "meminfo", "cpuinfo"}, CommandOptions::WithTimeout(90).Build(),
    RunDumpsys("DUMPSYS", {"--skip", "meminfo", "cpuinfo"}, CommandOptions::WithTimeout(90).Build(),
               10);
               10);


    printf("========================================================\n");
    dprintf(STDOUT_FILENO, "========================================================\n");
    printf("== Checkins\n");
    dprintf(STDOUT_FILENO, "== Checkins\n");
    printf("========================================================\n");
    dprintf(STDOUT_FILENO, "========================================================\n");


    RunDumpsys("CHECKIN BATTERYSTATS", {"batterystats", "-c"});
    RunDumpsys("CHECKIN BATTERYSTATS", {"batterystats", "-c"});
    RunDumpsys("CHECKIN MEMINFO", {"meminfo", "--checkin"});
    RunDumpsys("CHECKIN MEMINFO", {"meminfo", "--checkin"});
@@ -1130,21 +1130,21 @@ static void dumpstate() {
    RunDumpsys("CHECKIN USAGESTATS", {"usagestats", "-c"});
    RunDumpsys("CHECKIN USAGESTATS", {"usagestats", "-c"});
    RunDumpsys("CHECKIN PACKAGE", {"package", "--checkin"});
    RunDumpsys("CHECKIN PACKAGE", {"package", "--checkin"});


    printf("========================================================\n");
    dprintf(STDOUT_FILENO, "========================================================\n");
    printf("== Running Application Activities\n");
    dprintf(STDOUT_FILENO, "== Running Application Activities\n");
    printf("========================================================\n");
    dprintf(STDOUT_FILENO, "========================================================\n");


    RunDumpsys("APP ACTIVITIES", {"activity", "all"});
    RunDumpsys("APP ACTIVITIES", {"activity", "all"});


    printf("========================================================\n");
    dprintf(STDOUT_FILENO, "========================================================\n");
    printf("== Running Application Services\n");
    dprintf(STDOUT_FILENO, "== Running Application Services\n");
    printf("========================================================\n");
    dprintf(STDOUT_FILENO, "========================================================\n");


    RunDumpsys("APP SERVICES", {"activity", "service", "all"});
    RunDumpsys("APP SERVICES", {"activity", "service", "all"});


    printf("========================================================\n");
    dprintf(STDOUT_FILENO, "========================================================\n");
    printf("== Running Application Providers\n");
    dprintf(STDOUT_FILENO, "== Running Application Providers\n");
    printf("========================================================\n");
    dprintf(STDOUT_FILENO, "========================================================\n");


    RunDumpsys("APP PROVIDERS", {"activity", "provider", "all"});
    RunDumpsys("APP PROVIDERS", {"activity", "provider", "all"});


@@ -1153,20 +1153,20 @@ static void dumpstate() {
    // collected.
    // collected.
    DumpModemLogs();
    DumpModemLogs();


    printf("========================================================\n");
    dprintf(STDOUT_FILENO, "========================================================\n");
    printf("== Final progress (pid %d): %d/%d (estimated %d)\n", ds.pid_, ds.progress_->Get(),
    dprintf(STDOUT_FILENO, "== Final progress (pid %d): %d/%d (estimated %d)\n", ds.pid_,
           ds.progress_->GetMax(), ds.progress_->GetInitialMax());
            ds.progress_->Get(), ds.progress_->GetMax(), ds.progress_->GetInitialMax());
    printf("========================================================\n");
    dprintf(STDOUT_FILENO, "========================================================\n");
    printf("== dumpstate: done (id %d)\n", ds.id_);
    dprintf(STDOUT_FILENO, "== dumpstate: done (id %d)\n", ds.id_);
    printf("========================================================\n");
    dprintf(STDOUT_FILENO, "========================================================\n");
}
}


void Dumpstate::DumpstateBoard() {
void Dumpstate::DumpstateBoard() {
    DurationReporter duration_reporter("dumpstate_board()");
    DurationReporter duration_reporter("dumpstate_board()");
    printf("========================================================\n");
    dprintf(STDOUT_FILENO, "========================================================\n");
    printf("== Board\n");
    dprintf(STDOUT_FILENO, "== Board\n");
    printf("========================================================\n");
    dprintf(STDOUT_FILENO, "========================================================\n");
    fflush(stdout);
    fsync(STDOUT_FILENO);


    android::sp<android::hardware::dumpstate::V1_0::IDumpstateDevice> dumpstate_device(
    android::sp<android::hardware::dumpstate::V1_0::IDumpstateDevice> dumpstate_device(
        android::hardware::dumpstate::V1_0::IDumpstateDevice::getService("DumpstateDevice"));
        android::hardware::dumpstate::V1_0::IDumpstateDevice::getService("DumpstateDevice"));
@@ -1204,8 +1204,8 @@ void Dumpstate::DumpstateBoard() {
    dumpstate_device->dumpstateBoard(handle);
    dumpstate_device->dumpstateBoard(handle);


    AddZipEntry("dumpstate-board.txt", path);
    AddZipEntry("dumpstate-board.txt", path);
    printf("*** See dumpstate-board.txt entry ***\n");
    dprintf(STDOUT_FILENO, "*** See dumpstate-board.txt entry ***\n");
    fflush(stdout);
    fsync(STDOUT_FILENO);


    native_handle_close(handle);
    native_handle_close(handle);
    native_handle_delete(handle);
    native_handle_delete(handle);
+66 −61
Original line number Original line Diff line number Diff line
@@ -97,9 +97,9 @@ DurationReporter::~DurationReporter() {
            MYLOGD("Duration of '%s': %.3fs\n", title_.c_str(), (float)elapsed / NANOS_PER_SEC);
            MYLOGD("Duration of '%s': %.3fs\n", title_.c_str(), (float)elapsed / NANOS_PER_SEC);
        } else {
        } else {
            // Use "Yoda grammar" to make it easier to grep|sort sections.
            // Use "Yoda grammar" to make it easier to grep|sort sections.
            printf("------ %.3fs was the duration of '%s' ------\n", (float)elapsed / NANOS_PER_SEC,
            dprintf(STDOUT_FILENO, "------ %.3fs was the duration of '%s' ------\n",
                   title_.c_str());
                    (float)elapsed / NANOS_PER_SEC, title_.c_str());
            fflush(stdout);
            fsync(STDOUT_FILENO);
        }
        }
    }
    }
}
}
@@ -227,16 +227,19 @@ void Dumpstate::SetProgress(std::unique_ptr<Progress> progress) {
}
}


void for_each_userid(void (*func)(int), const char *header) {
void for_each_userid(void (*func)(int), const char *header) {
    std::string title = header == nullptr ? "for_each_userid" : android::base::StringPrintf(
                                                                    "for_each_userid(%s)", header);
    DurationReporter duration_reporter(title);
    if (PropertiesHelper::IsDryRun()) return;
    if (PropertiesHelper::IsDryRun()) return;


    DIR *d;
    DIR *d;
    struct dirent *de;
    struct dirent *de;


    if (header) printf("\n------ %s ------\n", header);
    if (header) dprintf(STDOUT_FILENO, "\n------ %s ------\n", header);
    func(0);
    func(0);


    if (!(d = opendir("/data/system/users"))) {
    if (!(d = opendir("/data/system/users"))) {
        printf("Failed to open /data/system/users (%s)\n", strerror(errno));
        dprintf(STDOUT_FILENO, "Failed to open /data/system/users (%s)\n", strerror(errno));
        return;
        return;
    }
    }


@@ -256,11 +259,11 @@ static void __for_each_pid(void (*helper)(int, const char *, void *), const char
    struct dirent *de;
    struct dirent *de;


    if (!(d = opendir("/proc"))) {
    if (!(d = opendir("/proc"))) {
        printf("Failed to open /proc (%s)\n", strerror(errno));
        dprintf(STDOUT_FILENO, "Failed to open /proc (%s)\n", strerror(errno));
        return;
        return;
    }
    }


    if (header) printf("\n------ %s ------\n", header);
    if (header) dprintf(STDOUT_FILENO, "\n------ %s ------\n", header);
    while ((de = readdir(d))) {
    while ((de = readdir(d))) {
        int pid;
        int pid;
        int fd;
        int fd;
@@ -310,6 +313,9 @@ static void for_each_pid_helper(int pid, const char *cmdline, void *arg) {
}
}


void for_each_pid(for_each_pid_func func, const char *header) {
void for_each_pid(for_each_pid_func func, const char *header) {
    std::string title = header == nullptr ? "for_each_pid"
                                          : android::base::StringPrintf("for_each_pid(%s)", header);
    DurationReporter duration_reporter(title);
    if (PropertiesHelper::IsDryRun()) return;
    if (PropertiesHelper::IsDryRun()) return;


    __for_each_pid(for_each_pid_helper, header, (void *) func);
    __for_each_pid(for_each_pid_helper, header, (void *) func);
@@ -324,7 +330,7 @@ static void for_each_tid_helper(int pid, const char *cmdline, void *arg) {
    snprintf(taskpath, sizeof(taskpath), "/proc/%d/task", pid);
    snprintf(taskpath, sizeof(taskpath), "/proc/%d/task", pid);


    if (!(d = opendir(taskpath))) {
    if (!(d = opendir(taskpath))) {
        printf("Failed to open %s (%s)\n", taskpath, strerror(errno));
        dprintf(STDOUT_FILENO, "Failed to open %s (%s)\n", taskpath, strerror(errno));
        return;
        return;
    }
    }


@@ -364,6 +370,9 @@ static void for_each_tid_helper(int pid, const char *cmdline, void *arg) {
}
}


void for_each_tid(for_each_tid_func func, const char *header) {
void for_each_tid(for_each_tid_func func, const char *header) {
    std::string title = header == nullptr ? "for_each_tid"
                                          : android::base::StringPrintf("for_each_tid(%s)", header);
    DurationReporter duration_reporter(title);
    if (PropertiesHelper::IsDryRun()) return;
    if (PropertiesHelper::IsDryRun()) return;


    __for_each_pid(for_each_tid_helper, header, (void *) func);
    __for_each_pid(for_each_tid_helper, header, (void *) func);
@@ -381,7 +390,7 @@ void show_wchan(int pid, int tid, const char *name) {


    snprintf(path, sizeof(path), "/proc/%d/wchan", tid);
    snprintf(path, sizeof(path), "/proc/%d/wchan", tid);
    if ((fd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_CLOEXEC))) < 0) {
    if ((fd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_CLOEXEC))) < 0) {
        printf("Failed to open '%s' (%s)\n", path, strerror(errno));
        dprintf(STDOUT_FILENO, "Failed to open '%s' (%s)\n", path, strerror(errno));
        return;
        return;
    }
    }


@@ -390,14 +399,14 @@ void show_wchan(int pid, int tid, const char *name) {
    close(fd);
    close(fd);


    if (ret < 0) {
    if (ret < 0) {
        printf("Failed to read '%s' (%s)\n", path, strerror(save_errno));
        dprintf(STDOUT_FILENO, "Failed to read '%s' (%s)\n", path, strerror(save_errno));
        return;
        return;
    }
    }


    snprintf(name_buffer, sizeof(name_buffer), "%*s%s",
    snprintf(name_buffer, sizeof(name_buffer), "%*s%s",
             pid == tid ? 0 : 3, "", name);
             pid == tid ? 0 : 3, "", name);


    printf("%-7d %-32s %s\n", tid, name_buffer, buffer);
    dprintf(STDOUT_FILENO, "%-7d %-32s %s\n", tid, name_buffer, buffer);


    return;
    return;
}
}
@@ -447,7 +456,7 @@ void show_showtime(int pid, const char *name) {


    snprintf(path, sizeof(path), "/proc/%d/stat", pid);
    snprintf(path, sizeof(path), "/proc/%d/stat", pid);
    if ((fd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_CLOEXEC))) < 0) {
    if ((fd = TEMP_FAILURE_RETRY(open(path, O_RDONLY | O_CLOEXEC))) < 0) {
        printf("Failed to open '%s' (%s)\n", path, strerror(errno));
        dprintf(STDOUT_FILENO, "Failed to open '%s' (%s)\n", path, strerror(errno));
        return;
        return;
    }
    }


@@ -456,7 +465,7 @@ void show_showtime(int pid, const char *name) {
    close(fd);
    close(fd);


    if (ret < 0) {
    if (ret < 0) {
        printf("Failed to read '%s' (%s)\n", path, strerror(save_errno));
        dprintf(STDOUT_FILENO, "Failed to read '%s' (%s)\n", path, strerror(save_errno));
        return;
        return;
    }
    }


@@ -495,7 +504,7 @@ void show_showtime(int pid, const char *name) {
    if (iotime) {
    if (iotime) {
        snprdec(buffer, sizeof(buffer), 79, permille);
        snprdec(buffer, sizeof(buffer), 79, permille);
    }
    }
    puts(buffer); // adds a trailing newline
    dprintf(STDOUT_FILENO, "%s\n", buffer);


    return;
    return;
}
}
@@ -503,29 +512,29 @@ void show_showtime(int pid, const char *name) {
void do_dmesg() {
void do_dmesg() {
    const char *title = "KERNEL LOG (dmesg)";
    const char *title = "KERNEL LOG (dmesg)";
    DurationReporter duration_reporter(title);
    DurationReporter duration_reporter(title);
    printf("------ %s ------\n", title);
    dprintf(STDOUT_FILENO, "------ %s ------\n", title);


    if (PropertiesHelper::IsDryRun()) return;
    if (PropertiesHelper::IsDryRun()) return;


    /* Get size of kernel buffer */
    /* Get size of kernel buffer */
    int size = klogctl(KLOG_SIZE_BUFFER, NULL, 0);
    int size = klogctl(KLOG_SIZE_BUFFER, NULL, 0);
    if (size <= 0) {
    if (size <= 0) {
        printf("Unexpected klogctl return value: %d\n\n", size);
        dprintf(STDOUT_FILENO, "Unexpected klogctl return value: %d\n\n", size);
        return;
        return;
    }
    }
    char *buf = (char *) malloc(size + 1);
    char *buf = (char *) malloc(size + 1);
    if (buf == NULL) {
    if (buf == NULL) {
        printf("memory allocation failed\n\n");
        dprintf(STDOUT_FILENO, "memory allocation failed\n\n");
        return;
        return;
    }
    }
    int retval = klogctl(KLOG_READ_ALL, buf, size);
    int retval = klogctl(KLOG_READ_ALL, buf, size);
    if (retval < 0) {
    if (retval < 0) {
        printf("klogctl failure\n\n");
        dprintf(STDOUT_FILENO, "klogctl failure\n\n");
        free(buf);
        free(buf);
        return;
        return;
    }
    }
    buf[retval] = '\0';
    buf[retval] = '\0';
    printf("%s\n\n", buf);
    dprintf(STDOUT_FILENO, "%s\n\n", buf);
    free(buf);
    free(buf);
    return;
    return;
}
}
@@ -546,7 +555,7 @@ int Dumpstate::DumpFile(const std::string& title, const std::string& path) {


    UpdateProgress(WEIGHT_FILE);
    UpdateProgress(WEIGHT_FILE);


    fflush(stdout);
    fsync(STDOUT_FILENO);


    return status;
    return status;
}
}
@@ -588,7 +597,7 @@ int dump_files(const std::string& title, const char* dir, bool (*skip)(const cha
    int fd, retval = 0;
    int fd, retval = 0;


    if (!title.empty()) {
    if (!title.empty()) {
        printf("------ %s (%s) ------\n", title.c_str(), dir);
        dprintf(STDOUT_FILENO, "------ %s (%s) ------\n", title.c_str(), dir);
    }
    }
    if (PropertiesHelper::IsDryRun()) return 0;
    if (PropertiesHelper::IsDryRun()) return 0;


@@ -630,14 +639,14 @@ int dump_files(const std::string& title, const char* dir, bool (*skip)(const cha
        fd = TEMP_FAILURE_RETRY(open(newpath, O_RDONLY | O_NONBLOCK | O_CLOEXEC));
        fd = TEMP_FAILURE_RETRY(open(newpath, O_RDONLY | O_NONBLOCK | O_CLOEXEC));
        if (fd < 0) {
        if (fd < 0) {
            retval = fd;
            retval = fd;
            printf("*** %s: %s\n", newpath, strerror(errno));
            dprintf(STDOUT_FILENO, "*** %s: %s\n", newpath, strerror(errno));
            continue;
            continue;
        }
        }
        (*dump_from_fd)(NULL, newpath, fd);
        (*dump_from_fd)(NULL, newpath, fd);
    }
    }
    closedir(dirp);
    closedir(dirp);
    if (!title.empty()) {
    if (!title.empty()) {
        printf("\n");
        dprintf(STDOUT_FILENO, "\n");
    }
    }
    return retval;
    return retval;
}
}
@@ -651,11 +660,12 @@ int dump_file_from_fd(const char *title, const char *path, int fd) {


    int flags = fcntl(fd, F_GETFL);
    int flags = fcntl(fd, F_GETFL);
    if (flags == -1) {
    if (flags == -1) {
        printf("*** %s: failed to get flags on fd %d: %s\n", path, fd, strerror(errno));
        dprintf(STDOUT_FILENO, "*** %s: failed to get flags on fd %d: %s\n", path, fd,
                strerror(errno));
        close(fd);
        close(fd);
        return -1;
        return -1;
    } else if (!(flags & O_NONBLOCK)) {
    } else if (!(flags & O_NONBLOCK)) {
        printf("*** %s: fd must have O_NONBLOCK set.\n", path);
        dprintf(STDOUT_FILENO, "*** %s: fd must have O_NONBLOCK set.\n", path);
        close(fd);
        close(fd);
        return -1;
        return -1;
    }
    }
@@ -674,7 +684,7 @@ int Dumpstate::RunCommand(const std::string& title, const std::vector<std::strin
     * Ideally, it should use a options.EstimatedDuration() instead...*/
     * Ideally, it should use a options.EstimatedDuration() instead...*/
    UpdateProgress(options.Timeout());
    UpdateProgress(options.Timeout());


    fflush(stdout);
    fsync(STDOUT_FILENO);


    return status;
    return status;
}
}
@@ -720,7 +730,7 @@ static int compare_prop(const void *a, const void *b) {
void print_properties() {
void print_properties() {
    const char* title = "SYSTEM PROPERTIES";
    const char* title = "SYSTEM PROPERTIES";
    DurationReporter duration_reporter(title);
    DurationReporter duration_reporter(title);
    printf("------ %s ------\n", title);
    dprintf(STDOUT_FILENO, "------ %s ------\n", title);
    if (PropertiesHelper::IsDryRun()) return;
    if (PropertiesHelper::IsDryRun()) return;
    size_t i;
    size_t i;
    num_props = 0;
    num_props = 0;
@@ -731,7 +741,7 @@ void print_properties() {
        fputs(props[i], stdout);
        fputs(props[i], stdout);
        free(props[i]);
        free(props[i]);
    }
    }
    printf("\n");
    dprintf(STDOUT_FILENO, "\n");
}
}


int open_socket(const char *service) {
int open_socket(const char *service) {
@@ -985,7 +995,7 @@ void dump_route_tables() {
    ds.DumpFile("RT_TABLES", RT_TABLES_PATH);
    ds.DumpFile("RT_TABLES", RT_TABLES_PATH);
    FILE* fp = fopen(RT_TABLES_PATH, "re");
    FILE* fp = fopen(RT_TABLES_PATH, "re");
    if (!fp) {
    if (!fp) {
        printf("*** %s: %s\n", RT_TABLES_PATH, strerror(errno));
        dprintf(STDOUT_FILENO, "*** %s: %s\n", RT_TABLES_PATH, strerror(errno));
        return;
        return;
    }
    }
    char table[16];
    char table[16];
@@ -1092,44 +1102,42 @@ void dump_emmc_ecsd(const char *ext_csd_path) {
        return;
        return;
    }
    }


    printf("------ %s Extended CSD ------\n", ext_csd_path);
    dprintf(STDOUT_FILENO, "------ %s Extended CSD ------\n", ext_csd_path);


    if (buffer.length() < (EXT_CSD_REV + sizeof(hex))) {
    if (buffer.length() < (EXT_CSD_REV + sizeof(hex))) {
        printf("*** %s: truncated content %zu\n\n", ext_csd_path, buffer.length());
        dprintf(STDOUT_FILENO, "*** %s: truncated content %zu\n\n", ext_csd_path, buffer.length());
        return;
        return;
    }
    }


    int ext_csd_rev = 0;
    int ext_csd_rev = 0;
    std::string sub = buffer.substr(EXT_CSD_REV, sizeof(hex));
    std::string sub = buffer.substr(EXT_CSD_REV, sizeof(hex));
    if (sscanf(sub.c_str(), "%2x", &ext_csd_rev) != 1) {
    if (sscanf(sub.c_str(), "%2x", &ext_csd_rev) != 1) {
        printf("*** %s: EXT_CSD_REV parse error \"%s\"\n\n",
        dprintf(STDOUT_FILENO, "*** %s: EXT_CSD_REV parse error \"%s\"\n\n", ext_csd_path,
               ext_csd_path, sub.c_str());
                sub.c_str());
        return;
        return;
    }
    }


    static const char *ver_str[] = {
    static const char *ver_str[] = {
        "4.0", "4.1", "4.2", "4.3", "Obsolete", "4.41", "4.5", "5.0"
        "4.0", "4.1", "4.2", "4.3", "Obsolete", "4.41", "4.5", "5.0"
    };
    };
    printf("rev 1.%d (MMC %s)\n",
    dprintf(STDOUT_FILENO, "rev 1.%d (MMC %s)\n", ext_csd_rev,
           ext_csd_rev,
            (ext_csd_rev < (int)(sizeof(ver_str) / sizeof(ver_str[0]))) ? ver_str[ext_csd_rev]
           (ext_csd_rev < (int)(sizeof(ver_str) / sizeof(ver_str[0]))) ?
                                                                        : "Unknown");
               ver_str[ext_csd_rev] :
               "Unknown");
    if (ext_csd_rev < 7) {
    if (ext_csd_rev < 7) {
        printf("\n");
        dprintf(STDOUT_FILENO, "\n");
        return;
        return;
    }
    }


    if (buffer.length() < (EXT_PRE_EOL_INFO + sizeof(hex))) {
    if (buffer.length() < (EXT_PRE_EOL_INFO + sizeof(hex))) {
        printf("*** %s: truncated content %zu\n\n", ext_csd_path, buffer.length());
        dprintf(STDOUT_FILENO, "*** %s: truncated content %zu\n\n", ext_csd_path, buffer.length());
        return;
        return;
    }
    }


    int ext_pre_eol_info = 0;
    int ext_pre_eol_info = 0;
    sub = buffer.substr(EXT_PRE_EOL_INFO, sizeof(hex));
    sub = buffer.substr(EXT_PRE_EOL_INFO, sizeof(hex));
    if (sscanf(sub.c_str(), "%2x", &ext_pre_eol_info) != 1) {
    if (sscanf(sub.c_str(), "%2x", &ext_pre_eol_info) != 1) {
        printf("*** %s: PRE_EOL_INFO parse error \"%s\"\n\n",
        dprintf(STDOUT_FILENO, "*** %s: PRE_EOL_INFO parse error \"%s\"\n\n", ext_csd_path,
               ext_csd_path, sub.c_str());
                sub.c_str());
        return;
        return;
    }
    }


@@ -1139,11 +1147,10 @@ void dump_emmc_ecsd(const char *ext_csd_path) {
        "Warning (consumed 80% of reserve)",
        "Warning (consumed 80% of reserve)",
        "Urgent (consumed 90% of reserve)"
        "Urgent (consumed 90% of reserve)"
    };
    };
    printf("PRE_EOL_INFO %d (MMC %s)\n",
    dprintf(
           ext_pre_eol_info,
        STDOUT_FILENO, "PRE_EOL_INFO %d (MMC %s)\n", ext_pre_eol_info,
           eol_str[(ext_pre_eol_info < (int)
        eol_str[(ext_pre_eol_info < (int)(sizeof(eol_str) / sizeof(eol_str[0]))) ? ext_pre_eol_info
                       (sizeof(eol_str) / sizeof(eol_str[0]))) ?
                                                                                 : 0]);
                           ext_pre_eol_info : 0]);


    for (size_t lifetime = EXT_DEVICE_LIFE_TIME_EST_TYP_A;
    for (size_t lifetime = EXT_DEVICE_LIFE_TIME_EST_TYP_A;
            lifetime <= EXT_DEVICE_LIFE_TIME_EST_TYP_B;
            lifetime <= EXT_DEVICE_LIFE_TIME_EST_TYP_B;
@@ -1165,28 +1172,26 @@ void dump_emmc_ecsd(const char *ext_csd_path) {
        };
        };


        if (buffer.length() < (lifetime + sizeof(hex))) {
        if (buffer.length() < (lifetime + sizeof(hex))) {
            printf("*** %s: truncated content %zu\n", ext_csd_path, buffer.length());
            dprintf(STDOUT_FILENO, "*** %s: truncated content %zu\n", ext_csd_path, buffer.length());
            break;
            break;
        }
        }


        ext_device_life_time_est = 0;
        ext_device_life_time_est = 0;
        sub = buffer.substr(lifetime, sizeof(hex));
        sub = buffer.substr(lifetime, sizeof(hex));
        if (sscanf(sub.c_str(), "%2x", &ext_device_life_time_est) != 1) {
        if (sscanf(sub.c_str(), "%2x", &ext_device_life_time_est) != 1) {
            printf("*** %s: DEVICE_LIFE_TIME_EST_TYP_%c parse error \"%s\"\n",
            dprintf(STDOUT_FILENO, "*** %s: DEVICE_LIFE_TIME_EST_TYP_%c parse error \"%s\"\n",
                    ext_csd_path,
                    ext_csd_path,
                   (unsigned)((lifetime - EXT_DEVICE_LIFE_TIME_EST_TYP_A) /
                    (unsigned)((lifetime - EXT_DEVICE_LIFE_TIME_EST_TYP_A) / sizeof(hex)) + 'A',
                              sizeof(hex)) + 'A',
                    sub.c_str());
                    sub.c_str());
            continue;
            continue;
        }
        }
        printf("DEVICE_LIFE_TIME_EST_TYP_%c %d (MMC %s)\n",
        dprintf(STDOUT_FILENO, "DEVICE_LIFE_TIME_EST_TYP_%c %d (MMC %s)\n",
               (unsigned)((lifetime - EXT_DEVICE_LIFE_TIME_EST_TYP_A) /
                (unsigned)((lifetime - EXT_DEVICE_LIFE_TIME_EST_TYP_A) / sizeof(hex)) + 'A',
                          sizeof(hex)) + 'A',
                ext_device_life_time_est,
                ext_device_life_time_est,
               est_str[(ext_device_life_time_est < (int)
                est_str[(ext_device_life_time_est < (int)(sizeof(est_str) / sizeof(est_str[0])))
                           (sizeof(est_str) / sizeof(est_str[0]))) ?
                            ? ext_device_life_time_est
                               ext_device_life_time_est : 0]);
                            : 0]);
    }
    }


    printf("\n");
    dprintf(STDOUT_FILENO, "\n");
}
}