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
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,
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;
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;
}
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;