From: Yousong Zhou Date: Tue, 31 Mar 2015 16:20:18 +0000 (+0800) Subject: Fix delta path handling. X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=3c7f3556b0039a19ddd3e263286085f6896da0eb;p=oweals%2Fuci.git 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. --- 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);