// clang-format on
};
-struct kmod_elf *kmod_file_get_elf(struct kmod_file *file)
+int kmod_file_get_elf(struct kmod_file *file, struct kmod_elf **elf)
{
- int err;
-
- if (file->elf)
- return file->elf;
-
- err = kmod_file_load_contents(file);
- if (err) {
- errno = -err;
- return NULL;
+ if (!file->elf) {
+ int err = kmod_file_load_contents(file);
+ if (err)
+ return err;
+
+ err = kmod_elf_new(file->memory, file->size, &file->elf);
+ if (err)
+ return err;
}
- err = kmod_elf_new(file->memory, file->size, &file->elf);
- if (err) {
- errno = -err;
- return NULL;
- }
- return file->elf;
+ *elf = file->elf;
+ return 0;
}
-struct kmod_file *kmod_file_open(const struct kmod_ctx *ctx, const char *filename)
+int kmod_file_open(const struct kmod_ctx *ctx, const char *filename,
+ struct kmod_file **out_file)
{
- struct kmod_file *file;
+ _cleanup_free_ struct kmod_file *file;
char buf[7];
ssize_t sz;
+ int ret;
assert_cc(sizeof(magic_zstd) < sizeof(buf));
assert_cc(sizeof(magic_xz) < sizeof(buf));
assert_cc(sizeof(magic_zlib) < sizeof(buf));
file = calloc(1, sizeof(struct kmod_file));
- if (file == NULL)
- return NULL;
+ if (file == NULL) {
+ file = NULL;
+ return -ENOMEM;
+ }
file->fd = open(filename, O_RDONLY | O_CLOEXEC);
- if (file->fd < 0) {
- free(file);
- return NULL;
- }
+ if (file->fd < 0)
+ return -errno;
sz = pread_str_safe(file->fd, buf, sizeof(buf), 0);
if (sz != (sizeof(buf) - 1)) {
if (sz < 0)
- errno = -sz;
+ ret = (int)sz;
else
- errno = EINVAL;
+ ret = -EINVAL;
close(file->fd);
- free(file);
- return NULL;
+ return ret;
}
for (unsigned int i = 0; i < ARRAY_SIZE(comp_types); i++) {
file->ctx = ctx;
- return file;
+ *out_file = file;
+ file = NULL;
+ return 0;
}
/*
_nonnull_all_ bool kmod_module_is_builtin(struct kmod_module *mod);
/* libkmod-file.c */
-_must_check_ _nonnull_all_ struct kmod_file *kmod_file_open(const struct kmod_ctx *ctx, const char *filename);
-_nonnull_all_ struct kmod_elf *kmod_file_get_elf(struct kmod_file *file);
+struct kmod_file;
+struct kmod_elf;
+_must_check_ _nonnull_all_ int kmod_file_open(const struct kmod_ctx *ctx, const char *filename, struct kmod_file **file);
+_must_check_ _nonnull_all_ int kmod_file_get_elf(struct kmod_file *file, struct kmod_elf **elf);
_nonnull_all_ int kmod_file_load_contents(struct kmod_file *file);
_must_check_ _nonnull_all_ const void *kmod_file_get_contents(const struct kmod_file *file);
_must_check_ _nonnull_all_ off_t kmod_file_get_size(const struct kmod_file *file);
_nonnull_all_ void kmod_file_unref(struct kmod_file *file);
/* libkmod-elf.c */
-struct kmod_elf;
struct kmod_modversion {
uint64_t crc;
enum kmod_symbol_bind bind;
int err;
if (flags & (KMOD_INSERT_FORCE_VERMAGIC | KMOD_INSERT_FORCE_MODVERSION)) {
- elf = kmod_file_get_elf(mod->file);
- if (elf == NULL) {
- err = -errno;
+ err = kmod_file_get_elf(mod->file, &elf);
+ if (err)
return err;
- }
err = kmod_elf_strip(elf, flags, &stripped);
if (err) {
}
if (!mod->file) {
- mod->file = kmod_file_open(mod->ctx, path);
- if (mod->file == NULL) {
- err = -errno;
+ err = kmod_file_open(mod->ctx, path, &mod->file);
+ if (err)
return err;
- }
}
err = do_finit_module(mod, flags, args);
kmod_list_release(list, kmod_module_section_free);
}
-static struct kmod_elf *kmod_module_get_elf(const struct kmod_module *mod)
+static int kmod_module_get_elf(const struct kmod_module *mod, struct kmod_elf **elf)
{
if (mod->file == NULL) {
const char *path = kmod_module_get_path(mod);
+ int ret;
- if (path == NULL) {
- errno = ENOENT;
- return NULL;
- }
+ if (path == NULL)
+ return -ENOENT;
- ((struct kmod_module *)mod)->file = kmod_file_open(mod->ctx, path);
- if (mod->file == NULL)
- return NULL;
+ ret = kmod_file_open(mod->ctx, path, &((struct kmod_module *)mod)->file);
+ if (ret)
+ return ret;
}
- return kmod_file_get_elf(mod->file);
+ return kmod_file_get_elf(mod->file, elf);
}
struct kmod_module_info {
if (count < 0)
return count;
} else {
- elf = kmod_module_get_elf(mod);
- if (elf == NULL)
- return -errno;
+ ret = kmod_module_get_elf(mod, &elf);
+ if (ret)
+ return ret;
count = kmod_elf_get_modinfo_strings(elf, &strings);
if (count < 0)
assert(*list == NULL);
- elf = kmod_module_get_elf(mod);
- if (elf == NULL)
- return -errno;
+ ret = kmod_module_get_elf(mod, &elf);
+ if (ret)
+ return ret;
count = kmod_elf_get_modversions(elf, &versions);
if (count < 0)
assert(*list == NULL);
- elf = kmod_module_get_elf(mod);
- if (elf == NULL)
- return -errno;
+ ret = kmod_module_get_elf(mod, &elf);
+ if (ret)
+ return ret;
count = kmod_elf_get_symbols(elf, &symbols);
if (count < 0)
assert(*list == NULL);
- elf = kmod_module_get_elf(mod);
- if (elf == NULL)
- return -errno;
+ ret = kmod_module_get_elf(mod, &elf);
+ if (ret)
+ return ret;
count = kmod_elf_get_dependency_symbols(elf, &symbols);
if (count < 0)