[OpenWrt-Devel] [PATCH 2/2] Fix delta path handling.

Yousong Zhou yszhou4tech at gmail.com
Tue Mar 31 12:20:18 EDT 2015


 - Make ctx->savedir sit at the end of ctx->delta_path.
 - Add notes to uci_set_savedir() and uci_add_delta_path() to document
   the behaviour changes.
---
 delta.c  |   39 +++++++++++++++++++++++++++++++++------
 libuci.c |    1 +
 uci.h    |    6 ++++--
 3 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/delta.c b/delta.c
index cdd46bc..357f5c7 100644
--- a/delta.c
+++ b/delta.c
@@ -99,10 +99,25 @@ static void uci_delta_save(struct uci_context *ctx, FILE *f,
 int uci_set_savedir(struct uci_context *ctx, const char *dir)
 {
 	char *sdir;
+	struct uci_element *e, *tmp;
+	bool exists = false;
 
 	UCI_HANDLE_ERR(ctx);
 	UCI_ASSERT(ctx, dir != NULL);
 
+	/* Move dir to the end of ctx->delta_path */
+	uci_foreach_element_safe(&ctx->delta_path, tmp, e) {
+		if (!strcmp(e->name, dir)) {
+			exists = true;
+			uci_list_del(&e->list);
+			break;
+		}
+	}
+	if (!exists)
+		UCI_INTERNAL(uci_add_delta_path, ctx, dir);
+	else
+		uci_list_add(&ctx->delta_path, &e->list);
+
 	sdir = uci_strdup(ctx, dir);
 	if (ctx->savedir != uci_savedir)
 		free(ctx->savedir);
@@ -113,13 +128,21 @@ int uci_set_savedir(struct uci_context *ctx, const char *dir)
 int uci_add_delta_path(struct uci_context *ctx, const char *dir)
 {
 	struct uci_element *e;
+	struct uci_list *savedir;
 
 	UCI_HANDLE_ERR(ctx);
 	UCI_ASSERT(ctx, dir != NULL);
-	if (!strcmp(dir, ctx->savedir))
-		return -1;
+
+	/* Duplicate delta path is not allowed */
+	uci_foreach_element(&ctx->delta_path, e) {
+		if (!strcmp(e->name, dir))
+			UCI_THROW(ctx, UCI_ERR_DUPLICATE);
+	}
+
 	e = uci_alloc_generic(ctx, UCI_TYPE_PATH, dir, sizeof(struct uci_element));
-	uci_list_add(&ctx->delta_path, &e->list);
+	/* Keep savedir at the end of ctx->delta_path list */
+	savedir = ctx->delta_path.prev;
+	uci_list_insert(savedir->prev, &e->list);
 
 	return 0;
 }
@@ -297,21 +320,25 @@ __private int uci_load_delta(struct uci_context *ctx, struct uci_package *p, boo
 		if ((asprintf(&filename, "%s/%s", e->name, p->e.name) < 0) || !filename)
 			UCI_THROW(ctx, UCI_ERR_MEM);
 
-		uci_load_delta_file(ctx, p, filename, NULL, false);
+		changes += uci_load_delta_file(ctx, p, filename, NULL, false);
 		free(filename);
 	}
 
 	if ((asprintf(&filename, "%s/%s", ctx->savedir, p->e.name) < 0) || !filename)
 		UCI_THROW(ctx, UCI_ERR_MEM);
+	UCI_TRAP_SAVE(ctx, done);
+	f = uci_open_stream(ctx, filename, NULL, SEEK_SET, flush, false);
+	UCI_TRAP_RESTORE(ctx);
 
-	changes = uci_load_delta_file(ctx, p, filename, &f, flush);
 	if (flush && f && (changes > 0)) {
-		rewind(f);
 		if (ftruncate(fileno(f), 0) < 0) {
+			free(filename);
 			uci_close_stream(f);
 			UCI_THROW(ctx, UCI_ERR_IO);
 		}
 	}
+
+done:
 	free(filename);
 	uci_close_stream(f);
 	ctx->err = 0;
diff --git a/libuci.c b/libuci.c
index b17cda1..a9e70e8 100644
--- a/libuci.c
+++ b/libuci.c
@@ -60,6 +60,7 @@ struct uci_context *uci_alloc_context(void)
 
 	ctx->confdir = (char *) uci_confdir;
 	ctx->savedir = (char *) uci_savedir;
+	uci_add_delta_path(ctx, uci_savedir);
 
 	uci_list_add(&ctx->backends, &uci_file_backend.e.list);
 	ctx->backend = &uci_file_backend;
diff --git a/uci.h b/uci.h
index abba660..c5583ed 100644
--- a/uci.h
+++ b/uci.h
@@ -252,6 +252,8 @@ extern int uci_list_configs(struct uci_context *ctx, char ***list);
  * uci_set_savedir: override the default delta save directory
  * @ctx: uci context
  * @dir: directory name
+ *
+ * This will also try adding the specified dir to the end of delta pathes.
  */
 extern int uci_set_savedir(struct uci_context *ctx, const char *dir);
 
@@ -269,8 +271,8 @@ extern int uci_set_confdir(struct uci_context *ctx, const char *dir);
  *
  * This function allows you to add directories, which contain 'overlays'
  * for the active config, that will never be committed.
- * Caller of this API should ensure that no duplicate entries (including the
- * default search path, e.g. `UCI_SAVEDIR') should be added.
+ *
+ * Adding a duplicate directory will cause UCI_ERR_DUPLICATE be returned.
  */
 extern int uci_add_delta_path(struct uci_context *ctx, const char *dir);
 
-- 
1.7.10.4
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list