static void print_progress_bar(int percent, off_t pos, unsigned long speed, time_t eta) { int i; human_unit_t h; struct winsize w; int progress_bar_length; int prgbar_stars; ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); progress_bar_length = w.ws_col - 7 - 38; prgbar_stars = (int)((percent * progress_bar_length) / 100); printf("\033[2K\r%3d %% [", percent); for (i = 0; i++ < prgbar_stars; printf("*")); for (; i++ < progress_bar_length; printf(" ")); if (percent == 100) { #if defined(__i386__) || defined(__arm__) || defined(__APPLE__) printf("] %llu bytes", pos); #else printf("] %lu bytes", pos); #endif } else { bytes_to_unit(&h, pos); printf("] %.3f %s", h.b, h.unit); if (speed) { bytes_to_unit(&h, speed); printf(" - %.0f %s/s", h.b, h.unit); } if (eta) { printf(" ETA "); print_eta(eta); } } }
int monitor_processes(int *nb_pid) { int pid_count, fd_count, result_count; int i,j; pidinfo_t pidinfo_list[MAX_PIDS]; fdinfo_t fdinfo; fdinfo_t biggest_fd; int fdnum_list[MAX_FD_PER_PID]; off_t max_size; char fsize[64]; char fpos[64]; char ftroughput[64]; float perc; result_t results[MAX_RESULTS]; signed char still_there; signed char search_all = 1; pid_count = 0; if (proc_specifiq_name_cnt) { for (i = 0; i < proc_specifiq_name_cnt; ++i) pid_count += find_pids_by_binary_name(proc_specifiq_name[i], pidinfo_list + pid_count, MAX_PIDS - pid_count); search_all = 0; } if (proc_specifiq_pid) { pid_count += find_pid_by_id(proc_specifiq_pid, pidinfo_list + pid_count); search_all = 0; } if (search_all) { for (i = 0 ; proc_names[i] ; i++) { pid_count += find_pids_by_binary_name(proc_names[i], pidinfo_list + pid_count, MAX_PIDS - pid_count); if(pid_count >= MAX_PIDS) { nfprintf(stderr, "Found too much procs (max = %d)\n",MAX_PIDS); break; } } } *nb_pid = pid_count; if (!pid_count) { if (flag_quiet) return 0; if (flag_monitor || flag_monitor_continous) { clear(); refresh(); } nfprintf(stderr,"No command currently running: "); for (i = 0 ; proc_names[i] ; i++) { nfprintf(stderr,"%s, ", proc_names[i]); } nfprintf(stderr,"exiting.\n"); return 0; } result_count = 0; for (i = 0 ; i < pid_count ; i++) { fd_count = find_fd_for_pid(pidinfo_list[i].pid, fdnum_list, MAX_FD_PER_PID); max_size = 0; // let's find the biggest opened file for (j = 0 ; j < fd_count ; j++) { get_fdinfo(pidinfo_list[i].pid, fdnum_list[j], &fdinfo); if (fdinfo.size > max_size) { biggest_fd = fdinfo; max_size = fdinfo.size; } } if (!max_size) { // nothing found nprintf("[%5d] %s inactive/flushing/streaming/...\n", pidinfo_list[i].pid, pidinfo_list[i].name); continue; } // We've our biggest_fd now, let's store the result results[result_count].pid = pidinfo_list[i]; results[result_count].fd = biggest_fd; results[result_count].hbegin = NULL; results[result_count].hend = NULL; results[result_count].hsize = 0; result_count++; } // wait a bit, so we can estimate the throughput if (flag_throughput) usleep(1000000 * throughput_wait_secs); if (flag_monitor || flag_monitor_continous) { clear(); refresh(); } copy_and_clean_results(results, result_count, 1); for (i = 0 ; i < result_count ; i++) { if (flag_throughput) { still_there = get_fdinfo(results[i].pid.pid, results[i].fd.num, &fdinfo); if (still_there && strcmp(results[i].fd.name, fdinfo.name)) still_there = 0; // still there, but it's not the same file ! } else still_there = 0; if (!still_there) { // pid is no more here (or no throughput was asked), use initial info format_size(results[i].fd.pos, fpos); format_size(results[i].fd.size, fsize); perc = ((double)100 / (double)results[i].fd.size) * (double)results[i].fd.pos; } else { // use the newest info format_size(fdinfo.pos, fpos); format_size(fdinfo.size, fsize); perc = ((double)100 / (double)fdinfo.size) * (double)fdinfo.pos; } nprintf("[%5d] %s %s %.1f%% (%s / %s)", results[i].pid.pid, results[i].pid.name, results[i].fd.name, perc, fpos, fsize); if (flag_throughput && still_there) { // results[i] vs fdinfo long long usec_diff; off_t byte_diff; off_t bytes_per_sec; usec_diff = (fdinfo.tv.tv_sec - results[i].fd.tv.tv_sec) * 1000000L + (fdinfo.tv.tv_usec - results[i].fd.tv.tv_usec); byte_diff = fdinfo.pos - results[i].fd.pos; results[i].hsize += add_to_hlist(&results[i].hbegin, &results[i].hend, results[i].hsize, byte_diff / (usec_diff / 1000000.0)); bytes_per_sec = get_hlist_average(results[i].hbegin, results[i].hsize); format_size(bytes_per_sec, ftroughput); nprintf(" %s/s", ftroughput); if (bytes_per_sec && fdinfo.size - fdinfo.pos > 0) { print_eta((fdinfo.size - fdinfo.pos) / bytes_per_sec); } } nprintf("\n"); // Need to work on window width when using screen/watch/... //~ printf(" ["); //~ print_bar(perc, ws.ws_col-6); //~ printf("]\n"); } copy_and_clean_results(results, result_count, 0); return 0; }
int main(int argc, char *argv[]) { int pid_count, fd_count, result_count; int i,j; pidinfo_t pidinfo_list[MAX_PIDS]; fdinfo_t fdinfo; fdinfo_t biggest_fd; int fdnum_list[MAX_FD_PER_PID]; off_t max_size; char fsize[64]; char fpos[64]; char ftroughput[64]; struct winsize ws; float perc; result_t results[MAX_RESULTS]; signed char still_there; parse_options(argc,argv); // ws.ws_row, ws.ws_col ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws); pid_count = 0; if(!proc_specifiq) { for(i = 0 ; proc_names[i] ; i++) { pid_count += find_pids_by_binary_name(proc_names[i], pidinfo_list + pid_count, MAX_PIDS - pid_count); if(pid_count >= MAX_PIDS) { fprintf(stderr, "Found too much procs (max = %d)\n",MAX_PIDS); break; } } } else { pid_count += find_pids_by_binary_name(proc_specifiq, pidinfo_list + pid_count, MAX_PIDS - pid_count); } if(!pid_count) { if(flag_quiet) return 0; fprintf(stderr,"No command currently running: "); for(i = 0 ; proc_names[i] ; i++) { fprintf(stderr,"%s, ", proc_names[i]); } fprintf(stderr,"exiting.\n"); return 0; } result_count = 0; for(i = 0 ; i < pid_count ; i++) { fd_count = find_fd_for_pid(pidinfo_list[i].pid, fdnum_list, MAX_FD_PER_PID); max_size = 0; // let's find the biggest opened file for(j = 0 ; j < fd_count ; j++) { get_fdinfo(pidinfo_list[i].pid, fdnum_list[j], &fdinfo); if(fdinfo.size > max_size) { biggest_fd = fdinfo; max_size = fdinfo.size; } } if(!max_size) { // nothing found printf("[%5d] %s inactive/flushing/streaming/...\n", pidinfo_list[i].pid, pidinfo_list[i].name); continue; } // We've our biggest_fd now, let's store the result results[result_count].pid = pidinfo_list[i]; results[result_count].fd = biggest_fd; result_count++; } // wait a bit, so we can estimate the throughput if (flag_throughput) usleep(1000000 * throughput_wait_secs); for (i = 0 ; i < result_count ; i++) { if (flag_throughput) { still_there = get_fdinfo(results[i].pid.pid, results[i].fd.num, &fdinfo); if (still_there && strcmp(results[i].fd.name, fdinfo.name)) still_there = 0; // still there, but it's not the same file ! } else still_there = 0; if (!still_there) { // pid is no more here (or no throughput was asked), use initial info format_size(results[i].fd.pos, fpos); format_size(results[i].fd.size, fsize); perc = ((double)100 / (double)results[i].fd.size) * (double)results[i].fd.pos; } else { // use the newest info format_size(fdinfo.pos, fpos); format_size(fdinfo.size, fsize); perc = ((double)100 / (double)fdinfo.size) * (double)fdinfo.pos; } printf("[%5d] %s %s %.1f%% (%s / %s)", results[i].pid.pid, results[i].pid.name, results[i].fd.name, perc, fpos, fsize); if (flag_throughput && still_there) { // results[i] vs fdinfo long long usec_diff; off_t byte_diff; off_t bytes_per_sec; usec_diff = (fdinfo.tv.tv_sec - results[i].fd.tv.tv_sec) * 1000000L + (fdinfo.tv.tv_usec - results[i].fd.tv.tv_usec); byte_diff = fdinfo.pos - results[i].fd.pos; bytes_per_sec = byte_diff / (usec_diff / 1000000.0); format_size(bytes_per_sec, ftroughput); printf(" %s/s", ftroughput); if (bytes_per_sec && fdinfo.size - fdinfo.pos > 0) { print_eta((fdinfo.size - fdinfo.pos) / bytes_per_sec); } } printf("\n"); // Need to work on window width when using screen/watch/... //~ printf(" ["); //~ print_bar(perc, ws.ws_col-6); //~ printf("]\n"); } return 0; }