[PATCH 2/5] zlibsupport: introduce grab_data structure for storing file content, size and compress type

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Alexey Gladkov <gladkov.alexey@xxxxxxxxx>
---
 elfops.c      |    8 +++---
 elfops.h      |    4 +-
 elfops_core.c |    8 +++---
 modinfo.c     |   15 ++++++-----
 modprobe.c    |    2 +-
 zlibsupport.c |   69 ++++++++++++++++++++++++++++++--------------------------
 zlibsupport.h |   17 ++++++++++++-
 7 files changed, 71 insertions(+), 52 deletions(-)

diff --git a/elfops.c b/elfops.c
index 10e80ea..3468265 100644
--- a/elfops.c
+++ b/elfops.c
@@ -74,11 +74,11 @@ struct elf_file *grab_elf_file(const char *pathname)
 		errno = ENOMEM;
 		goto fail_free_file;
 	}
-	file->data = grab_file(pathname, &file->len);
-	if (!file->data)
+
+	if (grab_file(pathname, &file->fdata) < 0)
 		goto fail_free_pathname;
 
-	switch (elf_ident(file->data, file->len, &file->conv)) {
+	switch (elf_ident(file->fdata.data, file->fdata.size, &file->conv)) {
 	case ELFCLASS32:
 		file->ops = &mod_ops32;
 		break;
@@ -108,7 +108,7 @@ void release_elf_file(struct elf_file *file)
 	if (!file)
 		return;
 
-	release_file(file->data, file->len);
+	release_file(&file->fdata);
 	free(file->pathname);
 	free(file);
 
diff --git a/elfops.h b/elfops.h
index 52c1fd7..fd4b014 100644
--- a/elfops.h
+++ b/elfops.h
@@ -3,6 +3,7 @@
 #include <stdio.h>
 #include <stdint.h>
 #include "logging.h"
+#include "zlibsupport.h"
 
 /* All the icky stuff to do with manipulating 64 and 32-bit modules
    belongs here. */
@@ -29,8 +30,7 @@ struct elf_file
 	int conv;
 
 	/* File contents and length. */
-	void *data;
-	unsigned long len;
+	struct grab_data fdata;
 };
 
 /* Tables extracted from module by ops->fetch_tables(). */
diff --git a/elfops_core.c b/elfops_core.c
index 7150d39..8b8ed77 100644
--- a/elfops_core.c
+++ b/elfops_core.c
@@ -23,8 +23,8 @@ static void *PERBIT(get_section)(struct elf_file *module,
 				 ElfPERBIT(Shdr) **sechdr,
 				 unsigned long *secsize)
 {
-	void *data = module->data;
-	unsigned long len = module->len;
+	void *data = module->fdata.data;
+	unsigned long len = module->fdata.size;
 	int conv = module->conv;
 
 	ElfPERBIT(Ehdr) *hdr;
@@ -229,7 +229,7 @@ static struct string_table *PERBIT(load_dep_syms)(struct elf_file *module,
 	}
 
 	num_syms = size / sizeof(syms[0]);
-	hdr = module->data;
+	hdr = module->fdata.data;
 	conv = module->conv;
 	if (versions) {
 		versions_size = num_syms;
@@ -332,7 +332,7 @@ static void PERBIT(fetch_tables)(struct elf_file *module,
 	ElfPERBIT(Shdr) *sechdrs;
 	int conv;
 
-	hdr = module->data;
+	hdr = module->fdata.data;
 	conv = module->conv;
 
 	sechdrs = (void *)hdr + END(hdr->e_shoff, conv);
diff --git a/modinfo.c b/modinfo.c
index 1dd8469..9ae40f2 100644
--- a/modinfo.c
+++ b/modinfo.c
@@ -189,7 +189,7 @@ static struct elf_file *grab_module(const char *name,
 				    const char *basedir)
 {
 	char *data;
-	unsigned long size;
+	struct grab_data fdata;
 	struct utsname buf;
 	char *depname, *p, *moddir;
 	struct elf_file *module;
@@ -213,16 +213,17 @@ static struct elf_file *grab_module(const char *name,
 
 	/* Search for it in modules.dep. */
 	nofail_asprintf(&depname, "%s/%s", moddir, "modules.dep");
-	data = grab_file(depname, &size);
-	if (!data) {
+	if (grab_file(depname, &fdata) < 0) {
 		error("modinfo: could not open %s\n", depname);
 		free(depname);
 		return NULL;
 	}
 	free(depname);
 
-	for (p = data; p < data + size; p = next_line(p, data + size)) {
-		if (name_matches(p, data + size, name)) {
+	data = fdata.data;
+
+	for (p = data; p < data + fdata.size; p = next_line(p, data + fdata.size)) {
+		if (name_matches(p, data + fdata.size, name)) {
 			int namelen = strcspn(p, ":");
 			const char *dir;
 			char *filename;
@@ -238,7 +239,7 @@ static struct elf_file *grab_module(const char *name,
 			} else {
 				filename = strndup(p, namelen);
 			}
-			release_file(data, size);
+			release_file(&fdata);
 			module = grab_elf_file(filename);
 			if (!module)
 				error("modinfo: could not open %s: %s\n",
@@ -247,7 +248,7 @@ static struct elf_file *grab_module(const char *name,
 			return module;
 		}
 	}
-	release_file(data, size);
+	release_file(&fdata);
 	error("modinfo: could not find module %s\n", name);
 	return NULL;
 }
diff --git a/modprobe.c b/modprobe.c
index 5464f45..edf60d6 100644
--- a/modprobe.c
+++ b/modprobe.c
@@ -1792,7 +1792,7 @@ static int insmod(struct list_head *list,
 		goto out_elf_file;
 
 	/* request kernel linkage */
-	ret = init_module(module->data, module->len, opts);
+	ret = init_module(module->fdata.data, module->fdata.size, opts);
 	if (ret != 0) {
 		if (errno == EEXIST) {
 			if (flags & mit_first_time)
diff --git a/zlibsupport.c b/zlibsupport.c
index fc58f16..8936c7f 100644
--- a/zlibsupport.c
+++ b/zlibsupport.c
@@ -20,81 +20,86 @@
 #ifdef CONFIG_USE_ZLIB
 #include <zlib.h>
 
-static void *grab_contents(gzFile *gzfd, unsigned long *size)
+static int grab_contents(gzFile *gzfd, struct grab_data *fdata)
 {
 	unsigned int max = 16384;
-	void *buffer = NOFAIL(malloc(max));
 	int ret;
 
-	*size = 0;
-	while ((ret = gzread(gzfd, buffer + *size, max - *size)) > 0) {
-		*size += ret;
-		if (*size == max)
-			buffer = NOFAIL(realloc(buffer, max *= 2));
+	fdata->data = NOFAIL(malloc(max));
+	fdata->size = 0;
+
+	while ((ret = gzread(gzfd, fdata->data + fdata->size, max - fdata->size)) > 0) {
+		fdata->size += ret;
+		if (fdata->size == max)
+			fdata->data = NOFAIL(realloc(fdata->data, max *= 2));
 	}
 	if (ret < 0) {
-		free(buffer);
-		buffer = NULL;
+		free(fdata->data);
+		fdata->data = NULL;
+		return -1;
 	}
 
-	return buffer;
+	return 0;
 }
 
 /* gzopen handles uncompressed files transparently. */
-void *grab_file(const char *filename, unsigned long *size)
+int grab_file(const char *filename, struct grab_data *fdata)
 {
 	gzFile gzfd;
-	void *buffer;
 
 	errno = 0;
 	gzfd = gzopen(filename, "rb");
 	if (!gzfd) {
 		if (errno == ENOMEM)
 			fatal("Memory allocation failure in gzopen\n");
-		return NULL;
+		return -1;
+	}
+	if (grab_contents(gzfd, fdata) < 0) {
+		gzclose(gzfd);
+		return -1;
 	}
-	buffer = grab_contents(gzfd, size);
+	fdata->type = GZIP_FILE;
 	gzclose(gzfd);
-	return buffer;
+	return 0;
 }
 
-void release_file(void *data, unsigned long size)
+void release_file(struct grab_data *fdata)
 {
-	free(data);
+	free(fdata->data);
 }
 #else /* ... !CONFIG_USE_ZLIB */
 
-static void *grab_fd(int fd, unsigned long *size)
+static void *grab_fd(int fd, struct grab_data *fdata)
 {
 	struct stat st;
-	void *map;
 	int ret;
 
 	ret = fstat(fd, &st);
 	if (ret < 0)
-		return NULL;
-	*size = st.st_size;
-	map = mmap(0, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
-	if (map == MAP_FAILED)
-		map = NULL;
-	return map;
+		return -1;
+	fdata->size = st.st_size;
+	fdata->data = mmap(0, fdata->size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+	if (fdata->data == MAP_FAILED)
+		fdata->data = NULL;
+	return 0;
 }
 
-void *grab_file(const char *filename, unsigned long *size)
+int grab_file(const char *filename, struct grab_data *fdata)
 {
 	int fd;
-	void *map;
 
 	fd = open(filename, O_RDONLY, 0);
 	if (fd < 0)
-		return NULL;
-	map = grab_fd(fd, size);
+		return -1;
+	if (grab_fd(fd, fdata) < 0)
+		return -1;
+	fdata->type = PLAIN_FILE;
 	close(fd);
-	return map;
+	return 0;
 }
 
-void release_file(void *data, unsigned long size)
+void release_file(struct grab_data *fdata)
 {
-	munmap(data, size);
+	munmap(fdata->data, fdata->size);
 }
 #endif
diff --git a/zlibsupport.h b/zlibsupport.h
index 9ab0703..3eb4c2d 100644
--- a/zlibsupport.h
+++ b/zlibsupport.h
@@ -1,10 +1,23 @@
 #ifndef _ZLIB_SUPPORT_H
 #define _ZLIB_SUPPORT_H
 
+enum file_type
+{
+	PLAIN_FILE,
+	GZIP_FILE
+};
+
+struct grab_data
+{
+	enum file_type type;
+	unsigned long size;
+	void *data;
+};
+
 /* Grab file.  Decompresses if that is supported.  Returns NULL on error. */
-extern void *grab_file(const char *filename, unsigned long *size);
+extern int grab_file(const char *filename, struct grab_data *fdata);
 
 /* Free it up. */
-extern void release_file(void *data, unsigned long size);
+extern void release_file(struct grab_data *fdata);
 
 #endif /* _ZLIB_SUPPORT_H */
-- 
1.7.3.5

--
To unsubscribe from this list: send the line "unsubscribe linux-modules" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux