From: Lucas De Marchi Date: Sun, 29 Jan 2012 17:40:58 +0000 (-0200) Subject: libkmod-module: split creation of new modules to share code X-Git-Tag: v5~39 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9c7f3ad0a4fe4edb9cdef3db6f8d0d9be4483e3d;p=thirdparty%2Fkmod.git libkmod-module: split creation of new modules to share code Share code of module creation among the several new functions. With this we let the alias/modname/path parsing to the separate functions, and the rest with the common one. This fixes the issue of alias names not being able to contain dots. --- diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c index f320fc1b..e1a04ba9 100644 --- a/libkmod/libkmod-module.c +++ b/libkmod/libkmod-module.c @@ -180,6 +180,76 @@ void kmod_module_set_visited(struct kmod_module *mod, bool visited) mod->visited = visited; } +/* + * Memory layout with alias: + * + * struct kmod_module { + * hashkey -----. + * alias -----. | + * name ----. | | + * } | | | + * name <----------' | | + * alias <-----------' | + * name\alias <--------' + * + * Memory layout without alias: + * + * struct kmod_module { + * hashkey ---. + * alias -----|----> NULL + * name ----. | + * } | | + * name <----------'-' + * + * @key is "name\alias" or "name" (in which case alias == NULL) + */ +static int kmod_module_new(struct kmod_ctx *ctx, const char *key, + const char *name, size_t namelen, + const char *alias, size_t aliaslen, + struct kmod_module **mod) +{ + struct kmod_module *m; + size_t keylen; + + m = kmod_pool_get_module(ctx, key); + if (m != NULL) { + *mod = kmod_module_ref(m); + return 0; + } + + if (alias == NULL) + keylen = namelen; + else + keylen = namelen + aliaslen + 1; + + m = malloc(sizeof(*m) + (alias == NULL ? 1 : 2) * (keylen + 1)); + if (m == NULL) { + free(m); + return -ENOMEM; + } + + memset(m, 0, sizeof(*m)); + + m->ctx = kmod_ref(ctx); + m->name = (char *)m + sizeof(*m); + memcpy(m->name, key, keylen + 1); + if (alias == NULL) { + m->hashkey = m->name; + m->alias = NULL; + } else { + m->name[namelen] = '\0'; + m->alias = m->name + namelen + 1; + m->hashkey = m->name + keylen + 1; + memcpy(m->hashkey, key, keylen + 1); + } + + m->refcount = 1; + kmod_pool_add_module(ctx, m, m->hashkey); + *mod = m; + + return 0; +} + /** * kmod_module_new_from_name: * @ctx: kmod library context @@ -206,54 +276,15 @@ KMOD_EXPORT int kmod_module_new_from_name(struct kmod_ctx *ctx, const char *name, struct kmod_module **mod) { - struct kmod_module *m; size_t namelen; char name_norm[PATH_MAX]; - char *namesep; if (ctx == NULL || name == NULL || mod == NULL) return -ENOENT; - if (alias_normalize(name, name_norm, &namelen) < 0) { - DBG(ctx, "invalid alias: %s\n", name); - return -EINVAL; - } + modname_normalize(name, name_norm, &namelen); - m = kmod_pool_get_module(ctx, name_norm); - if (m != NULL) { - *mod = kmod_module_ref(m); - return 0; - } - - namesep = strchr(name_norm, '/'); - m = malloc(sizeof(*m) + (namesep == NULL ? 1 : 2) * namelen + 2); - if (m == NULL) { - free(m); - return -ENOMEM; - } - - memset(m, 0, sizeof(*m)); - - m->ctx = kmod_ref(ctx); - m->name = (char *)m + sizeof(*m); - memcpy(m->name, name_norm, namelen + 1); - - if (namesep) { - size_t len = namesep - name_norm; - - m->name[len] = '\0'; - m->alias = m->name + len + 1; - m->hashkey = m->name + namelen + 1; - memcpy(m->hashkey, name_norm, namelen + 1); - } else { - m->hashkey = m->name; - } - - m->refcount = 1; - kmod_pool_add_module(ctx, m, m->hashkey); - *mod = m; - - return 0; + return kmod_module_new(ctx, name_norm, name_norm, namelen, NULL, 0, mod); } int kmod_module_new_from_alias(struct kmod_ctx *ctx, const char *alias, @@ -269,9 +300,9 @@ int kmod_module_new_from_alias(struct kmod_ctx *ctx, const char *alias, memcpy(key, name, namelen); memcpy(key + namelen + 1, alias, aliaslen + 1); - key[namelen] = '/'; + key[namelen] = '\\'; - err = kmod_module_new_from_name(ctx, key, mod); + err = kmod_module_new(ctx, key, name, namelen, alias, aliaslen, mod); if (err < 0) return err; @@ -341,7 +372,7 @@ KMOD_EXPORT int kmod_module_new_from_path(struct kmod_ctx *ctx, free(abspath); else { ERR(ctx, "kmod_module '%s' already exists with different path: new-path='%s' old-path='%s'\n", - name, abspath, m->path); + name, abspath, m->path); free(abspath); return -EEXIST; } @@ -350,21 +381,11 @@ KMOD_EXPORT int kmod_module_new_from_path(struct kmod_ctx *ctx, return 0; } - m = malloc(sizeof(*m) + namelen + 1); - if (m == NULL) - return -errno; - - memset(m, 0, sizeof(*m)); + err = kmod_module_new(ctx, name, name, namelen, NULL, 0, &m); + if (err < 0) + return err; - m->ctx = kmod_ref(ctx); - m->name = (char *)m + sizeof(*m); - memcpy(m->name, name, namelen + 1); m->path = abspath; - m->hashkey = m->name; - m->refcount = 1; - - kmod_pool_add_module(ctx, m, m->hashkey); - *mod = m; return 0;