[pacman-dev] [PATCH] Normalize alpm download callback's frontend cb arguments

ivy.foster at gmail.com ivy.foster at gmail.com
Sat Jul 9 03:11:25 UTC 2016


From: Ivy Foster <ivy.foster at gmail.com>

When curl calls alpm's dlcb, alpm calls the frontend's cb with the
following (dlsize, totalsize) arguments:

0, -1: initialize
0, 0: no change since last call
x {x>0, x<y}, y {y>0}: data downloaded, total size known
x {x>0}, x: download finished

If total size is not known, do not call frontend cb (no change to
original behavior); alpm's callback shouldn't be called if there is a
download error.

See agregory's original spec here:
https://wiki.archlinux.org/index.php/User:Apg#download_callback
---
 lib/libalpm/dload.c   | 22 ++++++++++++++++------
 src/pacman/callback.c | 19 +++++++++++--------
 2 files changed, 27 insertions(+), 14 deletions(-)

diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c
index 31ae82c..f4e6a27 100644
--- a/lib/libalpm/dload.c
+++ b/lib/libalpm/dload.c
@@ -126,14 +126,24 @@ static int dload_progress_cb(void *file, double dltotal, double dlnow,
 	}
 
 	/* initialize the progress bar here to avoid displaying it when
-	 * a repo is up to date and nothing gets downloaded */
-	if(payload->prevprogress == 0) {
-		payload->handle->dlcb(payload->remote_name, 0, (off_t)dltotal);
-	}
-
+	 * a repo is up to date and nothing gets downloaded.
+	 * payload->handle->dlcb will receive the remote_name
+	 * and the following arguments:
+	 * 0, -1: download initialized
+	 * 0, 0: non-download event
+	 * x {x>0}, x: download complete
+	 * x {x>0, x<y}, y {y > 0}: download progress, expected total is known */
+	if(current_size == total_size) {
+		payload->handle->dlcb(payload->remote_name, (off_t)dlnow, (off_t)dltotal);
+	} else if(!payload->prevprogress) {
+		payload->handle->dlcb(payload->remote_name, 0, -1);
+	} else if(payload->prevprogress == current_size) {
+		payload->handle->dlcb(payload->remote_name, 0, 0);
+	} else {
 	/* do NOT include initial_size since it wasn't part of the package's
 	 * download_size (nor included in the total download size callback) */
-	payload->handle->dlcb(payload->remote_name, (off_t)dlnow, (off_t)dltotal);
+		payload->handle->dlcb(payload->remote_name, (off_t)dlnow, (off_t)dltotal);
+	}
 
 	payload->prevprogress = current_size;
 
diff --git a/src/pacman/callback.c b/src/pacman/callback.c
index ab3e14f..7f72b84 100644
--- a/src/pacman/callback.c
+++ b/src/pacman/callback.c
@@ -678,8 +678,13 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total)
 
 	const unsigned short cols = getcols();
 
-	if(config->noprogressbar || cols == 0 || file_total == -1) {
-		if(file_xfered == 0) {
+	/* Nothing has changed since last callback; stop here */
+	if(file_xfered == 0 && file_total == 0) {
+		return;
+	}
+
+	if(config->noprogressbar || cols == 0) {
+		if(file_xfered == 0 && file_total == -1) {
 			printf(_("downloading %s...\n"), filename);
 			fflush(stdout);
 		}
@@ -710,14 +715,9 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total)
 		total = file_total;
 	}
 
-	/* bogus values : stop here */
-	if(xfered > total || xfered < 0) {
-		return;
-	}
-
 	/* this is basically a switch on xfered: 0, total, and
 	 * anything else */
-	if(file_xfered == 0) {
+	if(file_xfered == 0 && file_total == -1) {
 		/* set default starting values, ensure we only call this once
 		 * if TotalDownload is enabled */
 		if(!totaldownload || (totaldownload && list_xfered == 0)) {
@@ -726,6 +726,9 @@ void cb_dl_progress(const char *filename, off_t file_xfered, off_t file_total)
 			rate_last = 0.0;
 			get_update_timediff(1);
 		}
+	} else if(xfered > total || xfered < 0) {
+		/* bogus values : stop here */
+		return;
 	} else if(file_xfered == file_total) {
 		/* compute final values */
 		int64_t timediff = get_time_ms() - initial_time;
-- 
2.9.0


More information about the pacman-dev mailing list