[pacman-dev] [PATCH] Rework package removal code

Dan McGee dan at archlinux.org
Fri Dec 23 11:16:58 EST 2011


Extract the actual unlinking of files into a new method, which
eliminates a goto used for flow control. Also fix up a few small issues
in the code:

* Unnecessary (unsigned long) cast, use '%zd' instead
* Total up errors returned from unlink_file calls and return to caller
* Be consistent with scriptlets- we run pre_remove on dbonly, so we
  should also run post_remove. Both can be disabled by way of the
  --noscriptlet argument.
* Don't pass an invalid pointer to oldpkg to the event callbacks;
  instead call the callback before we free the object.

Signed-off-by: Dan McGee <dan at archlinux.org>
---
 lib/libalpm/remove.c |   99 +++++++++++++++++++++++++++-----------------------
 1 files changed, 54 insertions(+), 45 deletions(-)

diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c
index 8967eff..b43d1a6 100644
--- a/lib/libalpm/remove.c
+++ b/lib/libalpm/remove.c
@@ -354,38 +354,15 @@ static int unlink_file(alpm_handle_t *handle, alpm_pkg_t *oldpkg,
 	return 0;
 }
 
-int _alpm_remove_single_package(alpm_handle_t *handle,
+static int remove_package_files(alpm_handle_t *handle,
 		alpm_pkg_t *oldpkg, alpm_pkg_t *newpkg,
 		size_t targ_count, size_t pkg_count)
 {
 	alpm_list_t *skip_remove;
-	size_t filenum = 0, position = 0;
-	const char *pkgname = oldpkg->name;
-	const char *pkgver = oldpkg->version;
 	alpm_filelist_t *filelist;
-	size_t i;
-
-	if(newpkg) {
-		_alpm_log(handle, ALPM_LOG_DEBUG, "removing old package first (%s-%s)\n",
-				pkgname, pkgver);
-	} else {
-		EVENT(handle, ALPM_EVENT_REMOVE_START, oldpkg, NULL);
-		_alpm_log(handle, ALPM_LOG_DEBUG, "removing package %s-%s\n",
-				pkgname, pkgver);
-
-		/* run the pre-remove scriptlet if it exists  */
-		if(alpm_pkg_has_scriptlet(oldpkg) &&
-				!(handle->trans->flags & ALPM_TRANS_FLAG_NOSCRIPTLET)) {
-			char *scriptlet = _alpm_local_db_pkgpath(handle->db_local,
-					oldpkg, "install");
-			_alpm_runscriptlet(handle, scriptlet, "pre_remove", pkgver, NULL, 0);
-			free(scriptlet);
-		}
-	}
-
-	if(handle->trans->flags & ALPM_TRANS_FLAG_DBONLY) {
-		goto db;
-	}
+	size_t i, filenum = 0, position = 0;
+	int err = 0;
+	int nosave = handle->trans->flags & ALPM_TRANS_FLAG_NOSAVE;
 
 	if(newpkg) {
 		alpm_filelist_t *newfiles;
@@ -416,32 +393,33 @@ int _alpm_remove_single_package(alpm_handle_t *handle,
 		alpm_file_t *file = filelist->files + i;
 		if(!can_remove_file(handle, file, skip_remove)) {
 			_alpm_log(handle, ALPM_LOG_DEBUG,
-					"not removing package '%s', can't remove all files\n", pkgname);
+					"not removing package '%s', can't remove all files\n",
+					oldpkg->name);
+			FREELIST(skip_remove);
 			RET_ERR(handle, ALPM_ERR_PKG_CANT_REMOVE, -1);
 		}
 		filenum++;
 	}
 
-	_alpm_log(handle, ALPM_LOG_DEBUG, "removing %ld files\n", (unsigned long)filenum);
+	_alpm_log(handle, ALPM_LOG_DEBUG, "removing %zd files\n", filenum);
 
 	if(!newpkg) {
 		/* init progress bar, but only on true remove transactions */
-		PROGRESS(handle, ALPM_PROGRESS_REMOVE_START, pkgname, 0,
+		PROGRESS(handle, ALPM_PROGRESS_REMOVE_START, oldpkg->name, 0,
 				pkg_count, targ_count);
 	}
 
 	/* iterate through the list backwards, unlinking files */
 	for(i = filelist->count; i > 0; i--) {
 		alpm_file_t *file = filelist->files + i - 1;
-		int percent;
-		/* TODO: check return code and handle accordingly */
-		unlink_file(handle, oldpkg, newpkg, file, skip_remove,
-				handle->trans->flags & ALPM_TRANS_FLAG_NOSAVE);
+		if(unlink_file(handle, oldpkg, newpkg, file, skip_remove, nosave) < 0) {
+			err++;
+		}
 
 		if(!newpkg) {
 			/* update progress bar after each file */
-			percent = (position * 100) / filenum;
-			PROGRESS(handle, ALPM_PROGRESS_REMOVE_START, pkgname,
+			int percent = (position * 100) / filenum;
+			PROGRESS(handle, ALPM_PROGRESS_REMOVE_START, oldpkg->name,
 					percent, pkg_count, targ_count);
 		}
 		position++;
@@ -450,20 +428,56 @@ int _alpm_remove_single_package(alpm_handle_t *handle,
 
 	if(!newpkg) {
 		/* set progress to 100% after we finish unlinking files */
-		PROGRESS(handle, ALPM_PROGRESS_REMOVE_START, pkgname, 100,
+		PROGRESS(handle, ALPM_PROGRESS_REMOVE_START, oldpkg->name, 100,
 				pkg_count, targ_count);
+	}
+
+	return err;
+}
+
+int _alpm_remove_single_package(alpm_handle_t *handle,
+		alpm_pkg_t *oldpkg, alpm_pkg_t *newpkg,
+		size_t targ_count, size_t pkg_count)
+{
+	const char *pkgname = oldpkg->name;
+	const char *pkgver = oldpkg->version;
+
+	if(newpkg) {
+		_alpm_log(handle, ALPM_LOG_DEBUG, "removing old package first (%s-%s)\n",
+				pkgname, pkgver);
+	} else {
+		EVENT(handle, ALPM_EVENT_REMOVE_START, oldpkg, NULL);
+		_alpm_log(handle, ALPM_LOG_DEBUG, "removing package %s-%s\n",
+				pkgname, pkgver);
 
-		/* run the post-remove script if it exists  */
+		/* run the pre-remove scriptlet if it exists  */
 		if(alpm_pkg_has_scriptlet(oldpkg) &&
 				!(handle->trans->flags & ALPM_TRANS_FLAG_NOSCRIPTLET)) {
 			char *scriptlet = _alpm_local_db_pkgpath(handle->db_local,
 					oldpkg, "install");
-			_alpm_runscriptlet(handle, scriptlet, "post_remove", pkgver, NULL, 0);
+			_alpm_runscriptlet(handle, scriptlet, "pre_remove", pkgver, NULL, 0);
 			free(scriptlet);
 		}
 	}
 
-db:
+	if(!(handle->trans->flags & ALPM_TRANS_FLAG_DBONLY)) {
+		/* TODO check returned errors if any */
+		remove_package_files(handle, oldpkg, newpkg, targ_count, pkg_count);
+	}
+
+	/* run the post-remove script if it exists  */
+	if(!newpkg && alpm_pkg_has_scriptlet(oldpkg) &&
+			!(handle->trans->flags & ALPM_TRANS_FLAG_NOSCRIPTLET)) {
+		char *scriptlet = _alpm_local_db_pkgpath(handle->db_local,
+				oldpkg, "install");
+		_alpm_runscriptlet(handle, scriptlet, "post_remove", pkgver, NULL, 0);
+		free(scriptlet);
+	}
+
+	if(!newpkg) {
+		EVENT(handle, ALPM_EVENT_REMOVE_DONE, oldpkg, NULL);
+	}
+
 	/* remove the package from the database */
 	_alpm_log(handle, ALPM_LOG_DEBUG, "updating database\n");
 	_alpm_log(handle, ALPM_LOG_DEBUG, "removing database entry '%s'\n", pkgname);
@@ -477,11 +491,6 @@ db:
 				pkgname);
 	}
 
-	if(!newpkg) {
-		/* TODO: awesome! we're passing invalid pointers. */
-		EVENT(handle, ALPM_EVENT_REMOVE_DONE, oldpkg, NULL);
-	}
-
 	return 0;
 }
 
-- 
1.7.8.1



More information about the pacman-dev mailing list