summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYousong Zhou <yszhou4tech@gmail.com>2015-04-01 00:20:18 +0800
committerFelix Fietkau <nbd@openwrt.org>2015-03-31 18:42:41 +0200
commit3c7f3556b0039a19ddd3e263286085f6896da0eb (patch)
treecb6318648d0885d8bcbc1f24e9cd424d848cf8a6
parent3b3c554567154ad984e4e1146a3ada6ff99925f4 (diff)
downloaduci-3c7f3556b0039a19ddd3e263286085f6896da0eb.tar.gz
Fix delta path handling.
- 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.
-rw-r--r--delta.c39
-rw-r--r--libuci.c1
-rw-r--r--uci.h6
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);