Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/modutils/modutils.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 983 by niro, Fri Apr 24 18:33:46 2009 UTC revision 984 by niro, Sun May 30 11:32:42 2010 UTC
# Line 5  Line 5 
5   *   *
6   * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.   * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
7   */   */
   
8  #include "modutils.h"  #include "modutils.h"
9    
10  #ifdef __UCLIBC__  #ifdef __UCLIBC__
# Line 17  extern int delete_module(const char *mod Line 16  extern int delete_module(const char *mod
16  # define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags)  # define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags)
17  #endif  #endif
18    
 USE_FEATURE_2_4_MODULES(char *insmod_outputname);  
   
 /*  
  a libbb candidate from ice age!  
 */  
 llist_t FAST_FUNC *llist_find(llist_t *first, const char *str)  
 {  
  while (first != NULL) {  
  if (strcmp(first->data, str) == 0)  
  return first;  
  first = first->link;  
  }  
  return NULL;  
 }  
   
19  void FAST_FUNC replace(char *s, char what, char with)  void FAST_FUNC replace(char *s, char what, char with)
20  {  {
21   while (*s) {   while (*s) {
# Line 41  void FAST_FUNC replace(char *s, char wha Line 25  void FAST_FUNC replace(char *s, char wha
25   }   }
26  }  }
27    
28  char * FAST_FUNC replace_underscores(char *s)  char* FAST_FUNC replace_underscores(char *s)
29  {  {
30   replace(s, '-', '_');   replace(s, '-', '_');
31   return s;   return s;
# Line 61  int FAST_FUNC string_to_llist(char *stri Line 45  int FAST_FUNC string_to_llist(char *stri
45   return len;   return len;
46  }  }
47    
48  char * FAST_FUNC filename2modname(const char *filename, char *modname)  char* FAST_FUNC filename2modname(const char *filename, char *modname)
49  {  {
50   int i;   int i;
51   char *from;   char *from;
# Line 73  char * FAST_FUNC filename2modname(const Line 57  char * FAST_FUNC filename2modname(const
57   from = bb_get_last_path_component_nostrip(filename);   from = bb_get_last_path_component_nostrip(filename);
58   for (i = 0; i < (MODULE_NAME_LEN-1) && from[i] != '\0' && from[i] != '.'; i++)   for (i = 0; i < (MODULE_NAME_LEN-1) && from[i] != '\0' && from[i] != '.'; i++)
59   modname[i] = (from[i] == '-') ? '_' : from[i];   modname[i] = (from[i] == '-') ? '_' : from[i];
60   modname[i] = 0;   modname[i] = '\0';
61    
62   return modname;   return modname;
63  }  }
64    
65  const char * FAST_FUNC moderror(int err)  char* FAST_FUNC parse_cmdline_module_options(char **argv)
 {  
  switch (err) {  
  case -1:  
  return "no such module";  
  case ENOEXEC:  
  return "invalid module format";  
  case ENOENT:  
  return "unknown symbol in module, or unknown parameter";  
  case ESRCH:  
  return "module has wrong symbol version";  
  case ENOSYS:  
  return "kernel does not support requested operation";  
  default:  
  return strerror(err);  
  }  
 }  
   
 char * FAST_FUNC parse_cmdline_module_options(char **argv)  
66  {  {
67   char *options;   char *options;
68   int optlen;   int optlen;
# Line 111  char * FAST_FUNC parse_cmdline_module_op Line 77  char * FAST_FUNC parse_cmdline_module_op
77   return options;   return options;
78  }  }
79    
80    #if ENABLE_FEATURE_INSMOD_TRY_MMAP
81    void* FAST_FUNC try_to_mmap_module(const char *filename, size_t *image_size_p)
82    {
83     /* We have user reports of failure to load 3MB module
84     * on a 16MB RAM machine. Apparently even a transient
85     * memory spike to 6MB during module load
86     * is too big for that system. */
87     void *image;
88     struct stat st;
89     int fd;
90    
91     fd = xopen(filename, O_RDONLY);
92     fstat(fd, &st);
93     image = NULL;
94     /* st.st_size is off_t, we can't just pass it to mmap */
95     if (st.st_size <= *image_size_p) {
96     size_t image_size = st.st_size;
97     image = mmap(NULL, image_size, PROT_READ, MAP_PRIVATE, fd, 0);
98     if (image == MAP_FAILED) {
99     image = NULL;
100     } else if (*(uint32_t*)image != SWAP_BE32(0x7f454C46)) {
101     /* No ELF signature. Compressed module? */
102     munmap(image, image_size);
103     image = NULL;
104     } else {
105     /* Success. Report the size */
106     *image_size_p = image_size;
107     }
108     }
109     close(fd);
110     return image;
111    }
112    #endif
113    
114    /* Return:
115     * 0 on success,
116     * -errno on open/read error,
117     * errno on init_module() error
118     */
119  int FAST_FUNC bb_init_module(const char *filename, const char *options)  int FAST_FUNC bb_init_module(const char *filename, const char *options)
120  {  {
121   size_t len = MAXINT(ssize_t);   size_t image_size;
122   char *image;   char *image;
123   int rc = ENOENT;   int rc;
124     bool mmaped;
125    
126     if (!options)
127     options = "";
128    
129    //TODO: audit bb_init_module_24 to match error code convention
130  #if ENABLE_FEATURE_2_4_MODULES  #if ENABLE_FEATURE_2_4_MODULES
131   if (get_linux_version_code() < KERNEL_VERSION(2,6,0))   if (get_linux_version_code() < KERNEL_VERSION(2,6,0))
132   return bb_init_module_24(filename, options);   return bb_init_module_24(filename, options);
133  #endif  #endif
134    
135   /* Use the 2.6 way */   image_size = INT_MAX - 4095;
136   image = xmalloc_open_zipped_read_close(filename, &len);   mmaped = 0;
137     image = try_to_mmap_module(filename, &image_size);
138   if (image) {   if (image) {
139   if (init_module(image, len, options) != 0)   mmaped = 1;
140   rc = errno;   } else {
141   else   errno = ENOMEM; /* may be changed by e.g. open errors below */
142   rc = 0;   image = xmalloc_open_zipped_read_close(filename, &image_size);
143   free(image);   if (!image)
144     return -errno;
145   }   }
146    
147     errno = 0;
148     init_module(image, image_size, options);
149     rc = errno;
150     if (mmaped)
151     munmap(image, image_size);
152     else
153     free(image);
154   return rc;   return rc;
155  }  }
156    
157  int FAST_FUNC bb_delete_module(const char *module, unsigned int flags)  int FAST_FUNC bb_delete_module(const char *module, unsigned int flags)
158  {  {
159   return delete_module(module, flags);   errno = 0;
160     delete_module(module, flags);
161     return errno;
162    }
163    
164    const char* FAST_FUNC moderror(int err)
165    {
166     switch (err) {
167     case -1: /* btw: it's -EPERM */
168     return "no such module";
169     case ENOEXEC:
170     return "invalid module format";
171     case ENOENT:
172     return "unknown symbol in module, or unknown parameter";
173     case ESRCH:
174     return "module has wrong symbol version";
175     case ENOSYS:
176     return "kernel does not support requested operation";
177     }
178     if (err < 0) /* should always be */
179     err = -err;
180     return strerror(err);
181  }  }

Legend:
Removed from v.983  
changed lines
  Added in v.984