From 4885a7fa3a54e9a81831916c7925b2996b695f50 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Mon, 8 Aug 2011 18:18:09 -0500 Subject: Fix divide by zero when downloading zero length files If someone did a 'touch bogusrepo.db', we had the potential to throw a SIGFPE or divide by zero, given that the total file size was 0 and getting passed up to the pacman callback. Fix this so we get weird but sane output and don't blow up when downloading: :: Synchronizing package databases... core 35.7K 306.7K/s 00:00:00 [###################] 100% bogusrepo 0.0K 0.0K/s 00:00:00 [###################] 100% Exception as seen in gdb: Program received signal SIGFPE, Arithmetic exception. 0x000000000040cc73 in cb_dl_progress (filename=0x619dfc "bogusrepo.db", file_xfered=0, file_total=0) at callback.c:584 584 file_percent = (file_xfered * 100) / file_total; Signed-off-by: Dan McGee --- src/pacman/callback.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/pacman/callback.c b/src/pacman/callback.c index 46ff2e88..68672b4f 100644 --- a/src/pacman/callback.c +++ b/src/pacman/callback.c @@ -27,6 +27,7 @@ #include /* off_t */ #include #include +#include /* UINT_MAX */ #include @@ -561,10 +562,13 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total) diff_sec = current_time.tv_sec - initial_time.tv_sec; diff_usec = current_time.tv_usec - initial_time.tv_usec; timediff = diff_sec + (diff_usec / 1000000.0); - rate = xfered / (timediff * 1024.0); - - /* round elapsed time to the nearest second */ - eta_s = (int)(timediff + 0.5); + if(timediff > 0.0) { + rate = xfered / (timediff * 1024.0); + /* round elapsed time to the nearest second */ + eta_s = (unsigned int)(timediff + 0.5); + } else { + eta_s = 0; + } } else { /* compute current average values */ timediff = get_update_timediff(0); @@ -576,12 +580,20 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total) rate = (xfered - xfered_last) / (timediff * 1024.0); /* average rate to reduce jumpiness */ rate = (rate + 2 * rate_last) / 3; - eta_s = (total - xfered) / (rate * 1024.0); + if(rate > 0.0) { + eta_s = (total - xfered) / (rate * 1024.0); + } else { + eta_s = UINT_MAX; + } rate_last = rate; xfered_last = xfered; } - file_percent = (file_xfered * 100) / file_total; + if(file_total) { + file_percent = (file_xfered * 100) / file_total; + } else { + file_percent = 100; + } if(totaldownload) { total_percent = ((list_xfered + file_xfered) * 100) / @@ -658,6 +670,7 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total) } /* 1 space + filenamelen + 1 space + 7 for size + 1 + 7 for rate + 2 for /s + 1 space + 8 for eta */ + /* TODO: if eta_h > 99, formatting gets all messed up */ printf(" %ls%-*s %6.1f%c %#6.1f%c/s %02u:%02u:%02u", wcfname, padwid, "", f_xfered, xfered_size, rate, rate_size, eta_h, eta_m, eta_s); -- cgit v1.2.3-24-g4f1b