[BusyBox] [patch] Add bunzip2 support to insmod

Rob Landley rob at landley.net
Wed Aug 17 23:05:46 UTC 2005


Cleaning this up to do a memory-to-memory bunzip2 without the extra temporary 
buffering and copying was easy.  Fixing it so CONFIG_FEATURE_CLEAN_UP had 
even a _chance_ of working, not so much.  (Using munmap means you have to 
keep trace of the exact size of what you're unmapping, and the size of the 
allocation is not the same thing as the size of the data you're using...)

So I ripped out the mmap and made it just malloc/read everywhere.  Just so 
cleaning up after itself was doable.

The following patch (against current cvs) compiles.  I have no idea if this is 
a useful observation.

Index: modutils/insmod.c
===================================================================
--- modutils/insmod.c (revision 11171)
+++ modutils/insmod.c (working copy)
@@ -84,6 +84,9 @@
 #include <fcntl.h>
 #include <sys/utsname.h>
 #include "busybox.h"
+#ifdef CONFIG_FEATURE_2_6_MODULES_BUNZIP2
+#include "unarchive.h"
+#endif
 
 #if !defined(CONFIG_FEATURE_2_4_MODULES) && \
  !defined(CONFIG_FEATURE_2_6_MODULES)
@@ -3507,24 +3510,7 @@
    new_add_ksymtab(f, sym);
  }
  free(absolute_filename);
-#ifdef _NOT_SUPPORTED_
- /* record where the persistent data is going, same address as previous 
symbol */
-
- if (f->persist) {
-  l = sizeof(symprefix)+  /* "__insmod_" */
-   lm_name+  /* module name */
-   2+   /* "_P" */
-   strlen(f->persist)+ /* data store */
-   1;   /* nul */
-  name = xmalloc(l);
-  snprintf(name, l, "%s%s_P%s",
-    symprefix, m_name, f->persist);
-  sym = obj_add_symbol(f, name, -1, ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE),
-    sec->idx, sec->header.sh_addr, 0);
-  if (use_ksymtab)
-   new_add_ksymtab(f, sym);
- }
-#endif /* _NOT_SUPPORTED_ */
+ 
  /* tag the desired sections if size is non-zero */
 
  for (i = 0; i < sizeof(section_names)/sizeof(section_names[0]); ++i) {
@@ -4042,12 +4003,52 @@
  }
 
  fstat(fd, &st);
- len = st.st_size;
- map = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
- if (map == MAP_FAILED) {
-  bb_perror_msg_and_die("cannot mmap `%s'", filename);
+ len = read(fd, map = bb_xmalloc(st.st_size), st.st_size);
+ if (ENABLE_FEATURE_CLEAN_UP) close(fd);
+ if (len != st.st_zie) {
+  if (ENABLE_FEATURE_CLEAN_UP) free(map);
+  bb_perror_msg_and_die("cannot read `%s'", filename);
  }
 
+ /* If we support bunzip2 compression, try to uncompress it */
+ 
+ if (ENABLE_FEATURE_2_6_MODULES_BUNZIP2) {
+  bunzip_data *bzd;
+  
+  if(!start_bunzip(&bzd, -1, map, len)) {
+   unsigned long bzsize = 0, bzwritten = 0;
+   void *bzmap, *bzfree;
+
+   for(bzfree = bzmap = malloc(bzsize);
+    bzmap;
+    bzmap = realloc(bzmap,bzsize))
+   {
+    int i = read_bunzip(bzd, bzmap + bzwritten, bzsize - bzwritten);
+
+    bzfree = bzmap;
+    if(i < dsize - bzwritten) {
+     if(i < 0) bzmap = 0;
+     else {
+      /* Success.  Use the uncompressed version */
+      if (ENABLE_FEATURE_CLEAN_UP) {
+       free(map);
+       bzfree = 0;
+      }
+      map = bzmap;
+      len = bzwritten;
+     }
+     break;
+    }
+    bzmap = realloc(bzmap, bzsize += len);
+   }
+   if(ENABLE_FEATURE_CLEAN_UP) {
+    free(bzfree);
+    free(bzd->dbuf);
+    free(bzd);
+   }
+  }
+ }
+
  ret = syscall(__NR_init_module, map, len, options);
  if (ret != 0) {
   bb_perror_msg_and_die("cannot insert `%s': %s (%li)",





More information about the busybox mailing list