00001 #include "config.h"
00002
00003 #include "headers.h"
00004 #include "types.h"
00005 #include "error.h"
00006 #include "io.h"
00007 #include "display.h"
00008
00009 #ifdef HAVE_UNISTD_H
00010 # ifdef HAVE_SIGNAL_H
00011 # ifdef HAVE_TERMIOS_H
00012 # ifdef HAVE_SYS_IOCTL_H
00013 # define CAN_RESIZE
00014 # endif
00015 # endif
00016 # endif
00017 #endif
00018
00019 display d;
00020
00021 #ifdef CAN_RESIZE
00022 static void displayGetSize(void)
00023 {
00024 struct winsize size;
00025
00026 if (d.manual_width && d.manual_height)
00027 return;
00028 if (ioctl(STDERR_FILENO, TIOCGWINSZ, (char *)&size) < 0)
00029 return;
00030 if (!d.manual_width) {
00031 d.screen_width = size.ws_col;
00032 if (d.screen_width_minus_one)
00033 d.screen_width--;
00034 }
00035 if (!d.manual_height) {
00036 d.screen_height = size.ws_row;
00037 if (d.screen_height_minus_one)
00038 d.screen_height--;
00039 }
00040 }
00041
00042 int displaySetSigWinch(void);
00043
00044 static void sig_winch(int signo)
00045 {
00046 displayGetSize();
00047 displaySetSigWinch();
00048 }
00049
00050 int displaySetSigWinch(void)
00051 {
00052 if (isatty(STDERR_FILENO) != 0) {
00053 if (signal(SIGWINCH, sig_winch) == SIG_ERR) {
00054 return(1);
00055 }
00056 }
00057 return(0);
00058 }
00059 #endif
00060
00061 int displayInit(void)
00062 {
00063 int c;
00064
00065 d.start_time = 0;
00066 d.total_time = 0;
00067 d.current_time = 0;
00068 d.elapsed_time = 0;
00069 d.percent_complete = 0.0;
00070 d.display_interval = 1;
00071 d.overtime_flag = 0;
00072 d.k = 1024;
00073 d.twiddle = '-';
00074 for (c = 0; c < 80; c++)
00075 d.title[c] = 0;
00076 d.screen_width = 79;
00077 d.manual_width = 0;
00078 d.screen_width_minus_one = DEFAULT_SW_MINUS_ONE;
00079 d.screen_height = 23;
00080 d.manual_height = 0;
00081 d.screen_height_minus_one = DEFAULT_SH_MINUS_ONE;
00082 d.display_wait = 0;
00083 d.display_numeric = 0;
00084 d.display_twiddle = DEFAULT_DISPLAY_TWIDDLE;
00085 d.display_title = 1;
00086 d.display_datacount = 1;
00087 d.display_throughput = 1;
00088 d.display_time = 1;
00089 d.display_elapsed_only = 0;
00090 d.display_percent = 1;
00091 d.display_bar = 1;
00092 d.display_summary = 1;
00093 d.display_ansi = 0;
00094 d.display_throughput_bits = 0;
00095 d.display_count_bits = 0;
00096 d.space_bg_color = 0;
00097 d.twiddle_fg_color = "[32m";
00098 d.twiddle_bg_color = 0;
00099 d.twiddle_fg_bold = 0;
00100 d.title_fg_color = "[33m";
00101 d.title_bg_color = 0;
00102 d.title_fg_bold = 0;
00103 d.datacount_fg_color = "[32m";
00104 d.datacount_bg_color = 0;
00105 d.datacount_fg_bold = 1;
00106 d.throughput_label_fg_color = 0;
00107 d.throughput_label_bg_color = 0;
00108 d.throughput_label_fg_bold = 0;
00109 d.throughput_fg_color = "[32m";
00110 d.throughput_bg_color = 0;
00111 d.throughput_fg_bold = 1;
00112 d.time_label_fg_color = 0;
00113 d.time_label_bg_color = 0;
00114 d.time_label_fg_bold = 0;
00115 d.time_fg_color = "[32m";
00116 d.time_bg_color = 0;
00117 d.time_fg_bold = 1;
00118 d.percent_fg_color = "[32m";
00119 d.percent_bg_color = 0;
00120 d.percent_fg_bold = 1;
00121 d.bar_fg_color = "[33m";
00122 d.bar_bg_color = 0;
00123 d.bar_fg_bold = 1;
00124 d.barbrace_fg_color = "[31m";
00125 d.barbrace_bg_color = 0;
00126 d.barbrace_fg_bold = 0;
00127 d.bar_open_brace = '[';
00128 d.bar_close_brace = ']';
00129 d.bar_complete = '=';
00130 d.bar_incomplete = ' ';
00131 d.total_display_percent = 1;
00132 d.info_file = 0;
00133 d.info_fin = 0;
00134 d.info_num = 0;
00135 d.info_percent_threshold = 0.0;
00136 d.info_percent_count = 0.0;
00137 for (c = 0; c < 256; c++)
00138 d.info_line[c] = 0;
00139 return(0);
00140 }
00141
00142 int readline_infofile(void)
00143 {
00144 int c = 0;
00145
00146 for (c = 0; c < 256; c++) {
00147 d.info_line[c] = 0;
00148 }
00149 if (!feof(d.info_fin)) {
00150 fgets(d.info_line, (size_t)256, d.info_fin);
00151 }
00152 return(0);
00153 }
00154
00155 int is_delimiter_infofile(void)
00156 {
00157 if (strcmp(d.info_line, "@@@") == 0)
00158 return(1);
00159 if (strcmp(d.info_line, "@@@\n") == 0)
00160 return(1);
00161 return(0);
00162 }
00163
00164 int init_infofile(void)
00165 {
00166 d.info_fin = fopen(d.info_file, "r");
00167 if (d.info_fin == 0) {
00168 print_error(stderr, "Cannot open infofile for reading: %s", d.info_file);
00169 return(1);
00170 }
00171
00172 d.info_num = 1;
00173 while (!feof(d.info_fin)) {
00174 if (readline_infofile() != 0) {
00175 print_error(stderr, "Read error on infofile: %s", d.info_file);
00176 return(1);
00177 }
00178 if (is_delimiter_infofile()) {
00179 d.info_num++;
00180 }
00181 }
00182
00183 fclose(d.info_fin);
00184 d.info_fin = 0;
00185
00186 d.info_fin = fopen(d.info_file, "r");
00187 if (d.info_fin == 0) {
00188 print_error(stderr, "Cannot reopen infofile for reading: %s", d.info_file);
00189 return(1);
00190 }
00191
00192 d.info_percent_threshold = 100.0 / (float)(d.info_num);
00193 d.info_percent_count = d.info_percent_threshold;
00194
00195 return(0);
00196 }
00197
00198 int shutdown_infofile(void)
00199 {
00200 fclose(d.info_fin);
00201 return(0);
00202 }
00203
00204 void displayAnsiNormal(void)
00205 {
00206 if (d.display_ansi) {
00207 fprintf(stderr, "[0m");
00208 }
00209 }
00210
00211 void displayClearScreen(void)
00212 {
00213 if (d.display_ansi) {
00214 fprintf(stderr, "[J");
00215 }
00216 else {
00217 int c = 0;
00218
00219 for (c = 0; c < d.screen_height; c++) {
00220 fprintf(stderr, "\n");
00221 }
00222 }
00223 }
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 int displayInfo(void)
00244 {
00245 int c = 0;
00246
00247 if (d.info_fin == 0)
00248 return(0);
00249
00250 displayAnsiNormal();
00251 displayClearScreen();
00252 readline_infofile();
00253 while (!feof(d.info_fin) && !is_delimiter_infofile()) {
00254 fprintf(stderr, "%s", d.info_line);
00255 c++;
00256 readline_infofile();
00257 }
00258 while (c < d.screen_height) {
00259 c++;
00260 fprintf(stderr, "\n");
00261 }
00262 return(0);
00263 }
00264
00265 int displayNextInfo(void)
00266 {
00267 if (d.display_numeric != 0)
00268 return(0);
00269 if (d.info_fin == 0)
00270 return(0);
00271
00272 if (d.info_percent_count <= d.percent_complete) {
00273 displayInfo();
00274 d.info_percent_count += d.info_percent_threshold;
00275 }
00276 return(0);
00277 }
00278
00279 int displayBegin(void)
00280 {
00281 d.start_time = time(0);
00282 d.current_time = time(0);
00283
00284 #ifdef CAN_RESIZE
00285 displayGetSize();
00286 if (displaySetSigWinch() != 0) {
00287 print_error(stderr, "Could not install SIGWINCH signal handler");
00288 print_esup(stderr, "Window resize events will be ignored");
00289 }
00290 #endif
00291
00292 if (d.info_file != 0) {
00293 if (init_infofile() != 0) {
00294 return(1);
00295 }
00296 displayInfo();
00297 }
00298
00299 return(0);
00300 }
00301
00302 #define sec_per_hour 3600
00303 #define sec_per_minute 60
00304
00305 int calculateCountDisplay(
00306 uint64 *total_count,
00307 char **total_count_units,
00308 float *short_count,
00309 char **short_count_units
00310 )
00311 {
00312 uint64 num = 0;
00313 uint64 div = 1;
00314
00315 *total_count = io.total_write;
00316 if (d.display_count_bits)
00317 *total_count_units = "b";
00318 else
00319 *total_count_units = "B";
00320
00321 num = io.total_write;
00322
00323 if (d.display_count_bits) {
00324 *short_count_units = "b ";
00325 num *= 8;
00326 }
00327 else {
00328 *short_count_units = "B ";
00329 }
00330
00331 *short_count = 0.0;
00332
00333 if (num >= d.k) {
00334 if (d.display_count_bits)
00335 *short_count_units = "Kb";
00336 else
00337 *short_count_units = "KB";
00338 div = d.k;
00339 }
00340 if (num >= (d.k * d.k)) {
00341 if (d.display_count_bits)
00342 *short_count_units = "Mb";
00343 else
00344 *short_count_units = "MB";
00345 num /= d.k;
00346 }
00347 if (num >= (d.k * d.k)) {
00348 if (d.display_count_bits)
00349 *short_count_units = "Gb";
00350 else
00351 *short_count_units = "GB";
00352 num /= d.k;
00353 }
00354 if (num >= (d.k * d.k)) {
00355 if (d.display_count_bits)
00356 *short_count_units = "Tb";
00357 else
00358 *short_count_units = "TB";
00359 num /= d.k;
00360 }
00361 if (num >= (d.k * d.k)) {
00362 if (d.display_count_bits)
00363 *short_count_units = "Pb";
00364 else
00365 *short_count_units = "PB";
00366 num /= d.k;
00367 }
00368 if (num >= (d.k * d.k)) {
00369 if (d.display_count_bits)
00370 *short_count_units = "Eb";
00371 else
00372 *short_count_units = "EB";
00373 num /= d.k;
00374 }
00375
00376 *short_count = ((float)num / div);
00377 return(0);
00378 }
00379
00380 int calculateThroughputDisplay(
00381 uint64 *total_throughput,
00382 char **total_throughput_units,
00383 float *short_throughput,
00384 char **short_throughput_units
00385 )
00386 {
00387 uint64 num = 0;
00388 uint64 div = 1;
00389
00390 if (d.elapsed_time > 0) {
00391 *total_throughput = io.total_write / d.elapsed_time;
00392 num = io.total_write / d.elapsed_time;
00393 }
00394 else {
00395 *total_throughput = 0;
00396 num = 0;
00397 }
00398 if (d.display_throughput_bits) {
00399 *total_throughput *= 8;
00400 *total_throughput_units = "b";
00401 *short_throughput_units = "b/s ";
00402 num *= 8;
00403 }
00404 else {
00405 *total_throughput_units = "B";
00406 *short_throughput_units = "B/s ";
00407 }
00408
00409 *short_throughput = 0.0;
00410
00411 if (num >= d.k) {
00412 if (d.display_throughput_bits)
00413 *short_throughput_units = "Kb/s";
00414 else
00415 *short_throughput_units = "KB/s";
00416 div = d.k;
00417 }
00418 if (num >= (d.k * d.k)) {
00419 if (d.display_throughput_bits)
00420 *short_throughput_units = "Mb/s";
00421 else
00422 *short_throughput_units = "MB/s";
00423 num /= d.k;
00424 }
00425 if (num >= (d.k * d.k)) {
00426 if (d.display_throughput_bits)
00427 *short_throughput_units = "Gb/s";
00428 else
00429 *short_throughput_units = "GB/s";
00430 num /= d.k;
00431 }
00432 if (num >= (d.k * d.k)) {
00433 if (d.display_throughput_bits)
00434 *short_throughput_units = "Tb/s";
00435 else
00436 *short_throughput_units = "TB/s";
00437 num /= d.k;
00438 }
00439 *short_throughput = ((float)num / div);
00440 return(0);
00441 }
00442
00443 int calculateTimeDisplay(uint64 *sptr, uint64 *mptr, uint64 *hptr)
00444 {
00445 if (*sptr >= sec_per_hour) {
00446 *hptr = *sptr / sec_per_hour;
00447 *sptr -= *hptr * sec_per_hour;
00448 }
00449 if (*sptr >= sec_per_minute) {
00450 *mptr = *sptr / sec_per_minute;
00451 *sptr -= *mptr * sec_per_minute;
00452 }
00453 return(0);
00454 }
00455
00456 int calculatePercentComplete(void)
00457 {
00458 if (io.total_size_known && (io.total_size > 0)) {
00459 d.percent_complete = (float)(io.total_write * 100.0 / io.total_size);
00460 if (d.percent_complete < 0) {
00461 d.percent_complete = 9999.9;
00462 }
00463 }
00464 return(0);
00465 }
00466
00467 void displayAnsi(char *fg, char *bg, int b)
00468 {
00469 if (d.display_ansi) {
00470 if (fg != 0) {
00471 fprintf(stderr, "%s", fg);
00472 }
00473 if (bg != 0) {
00474 fprintf(stderr, "%s", bg);
00475 }
00476 if (b) {
00477 fprintf(stderr, "[1m");
00478 }
00479 }
00480 }
00481
00482 void displayTwiddle(void)
00483 {
00484 static uint64 last_write = 0;
00485 static time_t last_time = 0;
00486
00487 if (last_time == 0) last_time = time(0);
00488 if (last_time == time(0)) return;
00489 if (last_write == io.total_write) return;
00490
00491 last_time = time(0);
00492 last_write = io.total_write;
00493
00494 switch (d.twiddle) {
00495 case '\\': d.twiddle = '|'; break;
00496 case '|': d.twiddle = '/'; break;
00497 case '/': d.twiddle = '-'; break;
00498 case '-': d.twiddle = '\\'; break;
00499 }
00500 displayAnsi(d.twiddle_fg_color, d.twiddle_bg_color, d.twiddle_fg_bold);
00501 fprintf(stderr, "%c\r", d.twiddle);
00502 }
00503
00504 int displayPrint(void)
00505 {
00506 uint64 eta = 0;
00507 uint64 total_throughput = 0;
00508 char *total_throughput_units = "";
00509 float short_throughput = 0.0;
00510 char* short_throughput_units = "";
00511 uint64 hours = 0;
00512 uint64 minutes = 0;
00513 uint64 seconds = 0;
00514 uint64 total_count = 0;
00515 char *total_count_units = "";
00516 float short_count = 0.0;
00517 char *short_count_units = "";
00518 char *time_title = "eta";
00519 int screen_used = 0;
00520 int this_width = 0;
00521
00522 if (d.display_wait && (io.total_write == 0)) {
00523 return(0);
00524 }
00525
00526 displayNextInfo();
00527
00528 d.current_time = time(0);
00529 d.elapsed_time = d.current_time - d.start_time;
00530
00531 if (
00532 calculateThroughputDisplay(
00533 &total_throughput,
00534 &total_throughput_units,
00535 &short_throughput,
00536 &short_throughput_units
00537 )
00538 != 0
00539 )
00540 {
00541 return(1);
00542 }
00543
00544 if (calculatePercentComplete() != 0) {
00545 return(1);
00546 }
00547
00548 if (d.display_numeric != 0) {
00549 fprintf(stderr, "%d\n", (int)d.percent_complete);
00550 return(0);
00551 }
00552
00553 if ((io.total_size_known == 1) && (!d.display_elapsed_only)) {
00554 if (io.total_write > 0) {
00555 if (io.total_size >= io.total_write) {
00556 if (d.percent_complete > 0.0) {
00557 eta =
00558 (uint64)(
00559 100 * d.elapsed_time / d.percent_complete
00560 )
00561 - d.elapsed_time;
00562 }
00563 else {
00564 eta = (uint64)(-1);
00565 }
00566 }
00567 else {
00568 if (!d.overtime_flag) {
00569 d.overtime_flag = 1;
00570 d.total_time = d.elapsed_time;
00571 }
00572 eta = d.elapsed_time - d.total_time;
00573 time_title = "ovr";
00574 }
00575 }
00576 else {
00577 eta = 0;
00578 }
00579 seconds = eta;
00580 }
00581 else
00582 {
00583 seconds = d.elapsed_time;
00584 time_title = "elapsed";
00585 }
00586 if (calculateTimeDisplay(&seconds, &minutes, &hours) != 0) {
00587 return(1);
00588 }
00589
00590 if (
00591 calculateCountDisplay(
00592 &total_count,
00593 &total_count_units,
00594 &short_count,
00595 &short_count_units)
00596 != 0)
00597 {
00598 return(1);
00599 }
00600
00601
00602
00603
00604 this_width = 1;
00605 if ((d.display_twiddle) && (screen_used+this_width < d.screen_width)) {
00606 displayAnsi(
00607 d.twiddle_fg_color,
00608 d.twiddle_bg_color,
00609 d.twiddle_fg_bold);
00610 fprintf(stderr, "%c", d.twiddle);
00611 screen_used += this_width;
00612 }
00613
00614
00615
00616
00617 if ((d.display_title) && (d.title[0] != 0)) {
00618 this_width = strlen(d.title);
00619 if (screen_used > 0) {
00620 displayAnsiNormal();
00621 displayAnsi(0,d.space_bg_color,0);
00622 fprintf(stderr, " ");
00623 this_width++;
00624 }
00625 displayAnsiNormal();
00626 displayAnsi(
00627 d.title_fg_color,
00628 d.title_bg_color,
00629 d.title_fg_bold);
00630 fprintf(stderr, "%s", d.title);
00631 screen_used += this_width;
00632 }
00633
00634
00635
00636
00637 this_width = 8;
00638 if (screen_used > 0)
00639 this_width++;
00640 if ((d.display_datacount) && (screen_used+this_width < d.screen_width)) {
00641 if (screen_used > 0) {
00642 displayAnsiNormal();
00643 displayAnsi(0,d.space_bg_color,0);
00644 fprintf(stderr, " ");
00645 }
00646 displayAnsiNormal();
00647 displayAnsi(
00648 d.datacount_fg_color,
00649 d.datacount_bg_color,
00650 d.datacount_fg_bold);
00651 if (short_count > 9999.9) {
00652 fprintf(stderr, "+999.9%2.2s", short_count_units);
00653 }
00654 else {
00655 fprintf(stderr, "%6.1f%2.2s", short_count, short_count_units);
00656 }
00657 screen_used += this_width;
00658 }
00659
00660
00661
00662
00663 this_width = 13;
00664 if (!d.display_datacount)
00665 this_width -= 3;
00666 if (screen_used > 0)
00667 this_width++;
00668 if ((d.display_throughput) && (screen_used+this_width < d.screen_width)) {
00669 if (screen_used > 0) {
00670 displayAnsiNormal();
00671 displayAnsi(0,d.space_bg_color,0);
00672 fprintf(stderr, " ");
00673 }
00674 if (d.display_datacount) {
00675 displayAnsiNormal();
00676 displayAnsi(
00677 d.throughput_label_fg_color,
00678 d.throughput_label_bg_color,
00679 d.throughput_label_fg_bold);
00680 fprintf(stderr, "at");
00681 displayAnsiNormal();
00682 displayAnsi(0,d.space_bg_color,0);
00683 fprintf(stderr, " ");
00684 }
00685 displayAnsiNormal();
00686 displayAnsi(
00687 d.throughput_fg_color,
00688 d.throughput_bg_color,
00689 d.throughput_fg_bold);
00690 fprintf(stderr, "%6.1f%4.4s", short_throughput, short_throughput_units);
00691 screen_used += this_width;
00692 }
00693
00694
00695
00696
00697 this_width = 11+strlen(time_title);
00698 if (screen_used > 0)
00699 this_width += 2;
00700 if ((d.display_time) && (screen_used+this_width < d.screen_width)) {
00701 if (screen_used > 0) {
00702 displayAnsiNormal();
00703 displayAnsi(0,d.space_bg_color,0);
00704 fprintf(stderr, " ");
00705 }
00706 displayAnsiNormal();
00707 displayAnsi(
00708 d.time_label_fg_color,
00709 d.time_label_bg_color,
00710 d.time_label_fg_bold);
00711 fprintf(stderr, "%s:", time_title);
00712 displayAnsiNormal();
00713 displayAnsi(0,d.space_bg_color,0);
00714 fprintf(stderr, " ");
00715 displayAnsiNormal();
00716 displayAnsi(
00717 d.time_fg_color,
00718 d.time_bg_color,
00719 d.time_fg_bold);
00720 if (hours > 99) {
00721 fprintf(stderr, "+99:99:99");
00722 }
00723 else
00724 fprintf(stderr, "%3u:%2.2u:%2.2u",
00725 (unsigned int)hours,
00726 (unsigned int)minutes,
00727 (unsigned int)seconds);
00728 screen_used += this_width;
00729 }
00730
00731
00732
00733
00734 this_width = 5;
00735 if (screen_used > 0)
00736 this_width++;
00737 if ((d.display_percent) && (io.total_size_known)
00738 && (screen_used+this_width < d.screen_width))
00739 {
00740 if (screen_used > 0) {
00741 displayAnsiNormal();
00742 displayAnsi(0,d.space_bg_color,0);
00743 fprintf(stderr, " ");
00744 }
00745 displayAnsiNormal();
00746 displayAnsi(
00747 d.percent_fg_color,
00748 d.percent_bg_color,
00749 d.percent_fg_bold);
00750 if (d.percent_complete > 999) {
00751 fprintf(stderr, "+999%%");
00752 }
00753 else {
00754 fprintf(stderr, "%4d%%", (int)d.percent_complete);
00755 }
00756 screen_used += this_width;
00757 }
00758
00759
00760
00761
00762 this_width = 5;
00763 if (screen_used > 0)
00764 this_width++;
00765 if ((d.display_bar) && (io.total_size_known)
00766 && (screen_used+this_width < d.screen_width))
00767 {
00768 int c;
00769 int line_length;
00770 int completed_length = 0;
00771
00772 if (screen_used > 0) {
00773 displayAnsiNormal();
00774 displayAnsi(0,d.space_bg_color,0);
00775 fprintf(stderr, " ");
00776 screen_used++;
00777 }
00778 this_width = d.screen_width - screen_used + 1;
00779 line_length = this_width - 3;
00780 completed_length = line_length * d.percent_complete / 100;
00781 displayAnsiNormal();
00782 displayAnsi(
00783 d.barbrace_fg_color,
00784 d.barbrace_bg_color,
00785 d.barbrace_fg_bold);
00786 fprintf(stderr, "%c", d.bar_open_brace);
00787 displayAnsiNormal();
00788 displayAnsi(
00789 d.bar_fg_color,
00790 d.bar_bg_color,
00791 d.bar_fg_bold);
00792 for (c = 0; c < line_length; c++) {
00793 if (c <= completed_length) {
00794 fprintf(stderr, "%c", d.bar_complete);
00795 }
00796 else {
00797 fprintf(stderr, "%c", d.bar_incomplete);
00798 }
00799 }
00800 displayAnsiNormal();
00801 displayAnsi(
00802 d.barbrace_fg_color,
00803 d.barbrace_bg_color,
00804 d.barbrace_fg_bold);
00805 fprintf(stderr, "%c", d.bar_close_brace);
00806 }
00807
00808 displayAnsiNormal();
00809 fprintf(stderr, "\r");
00810
00811 return(0);
00812 }
00813
00814 int displayUpdate(void)
00815 {
00816 if (d.display_twiddle) displayTwiddle();
00817 if (time(0) < d.current_time + d.display_interval) return(0);
00818 if (displayPrint() != 0) return(1);
00819 return(0);
00820 }
00821
00822 int displayEnd(void)
00823 {
00824 uint64 total_throughput = 0;
00825 char *total_throughput_units = "";
00826 float short_throughput = 0.0;
00827 char *short_throughput_units = "";
00828 uint64 total_count = 0;
00829 char *total_count_units = "";
00830 float short_count = 0.0;
00831 char *short_count_units = "";
00832 uint64 hours = 0;
00833 uint64 minutes = 0;
00834 uint64 seconds = 0;
00835
00836 displayPrint();
00837 d.elapsed_time = d.current_time - d.start_time;
00838
00839 if (calculatePercentComplete() != 0) {
00840 return(1);
00841 }
00842
00843 if (
00844 calculateCountDisplay(
00845 &total_count,
00846 &total_count_units,
00847 &short_count,
00848 &short_count_units
00849 )
00850 != 0
00851 )
00852 {
00853 return(1);
00854 }
00855
00856 if (
00857 calculateThroughputDisplay(
00858 &total_throughput,
00859 &total_throughput_units,
00860 &short_throughput,
00861 &short_throughput_units
00862 )
00863 != 0
00864 )
00865 {
00866 return(1);
00867 }
00868
00869 seconds = d.elapsed_time;
00870 if (calculateTimeDisplay(&seconds, &minutes, &hours) != 0) {
00871 return(1);
00872 }
00873
00874 fprintf(stderr, "\n");
00875 if (d.display_summary) {
00876 fprintf(stderr, "Copied: %llu%s (%.1f%s)",
00877 (long long unsigned int)total_count,
00878 total_count_units,
00879 short_count,
00880 short_count_units
00881 );
00882 if (io.total_size_known && d.total_display_percent) {
00883 fprintf(stderr, " (%d%% of expected input)", (int)d.percent_complete);
00884 }
00885 fprintf(stderr, "\n");
00886
00887 fprintf(stderr, "Time: ");
00888 if (hours > 0) {
00889 fprintf(stderr, "%3u:%2.2u:%2.2u",
00890 (unsigned int)hours,
00891 (unsigned int)minutes,
00892 (unsigned int)seconds);
00893 }
00894 else if (minutes > 0) {
00895 fprintf(stderr, "%2.2u:%2.2u",
00896 (unsigned int)minutes,
00897 (unsigned int)seconds);
00898 }
00899 else {
00900 fprintf(stderr, "%2u seconds",
00901 (unsigned int)seconds);
00902 }
00903 fprintf(stderr, "\n");
00904
00905 if ((hours != 0) || (minutes != 0) || (seconds != 0)) {
00906 fprintf(stderr, "Throughput: %llu%s (%.1f%s)\n\n",
00907 (long long unsigned int)total_throughput,
00908 total_throughput_units,
00909 short_throughput,
00910 short_throughput_units
00911 );
00912 }
00913 else {
00914 fprintf(stderr, "Throughput: (infinite)\n\n");
00915 }
00916 }
00917
00918 d.start_time = 0;
00919
00920 return(0);
00921 }