diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-09-13 14:59:38 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-09-13 14:59:38 +0000 |
commit | ba1315d0fbe7fa43aa7481b5d6e92bd03b0152d5 (patch) | |
tree | b5b295f5382bd71c6184539feabf0ba061897131 /modutils/modutils.c | |
parent | 4f3209b9d4b24ebe9b76e3bfe8ddd87af5228af9 (diff) | |
download | busybox-w32-ba1315d0fbe7fa43aa7481b5d6e92bd03b0152d5.tar.gz busybox-w32-ba1315d0fbe7fa43aa7481b5d6e92bd03b0152d5.tar.bz2 busybox-w32-ba1315d0fbe7fa43aa7481b5d6e92bd03b0152d5.zip |
modutils/*: rewrite by Timo Teras <timo.teras AT iki.fi>
- a lot faster (linear algorithmic complexity, smaller memory foot print)
- a lot smaller (the old code was overly complicated)
- loading of aliases is now module-init-tools compliant
- blacklisting is done correctly (-b option added)
- module argument quoting done right
- depmod now correctly generates modules.symbols and modules.alias
add/remove: 16/21 grow/shrink: 4/6 up/down: 6930/-9316 Total: -2386 bytes
text data bss dec hex filename
806039 592 6680 813311 c68ff busybox_old
803498 592 6676 810766 c5f0e busybox_unstripped
Diffstat (limited to 'modutils/modutils.c')
-rw-r--r-- | modutils/modutils.c | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/modutils/modutils.c b/modutils/modutils.c new file mode 100644 index 000000000..18ea5374e --- /dev/null +++ b/modutils/modutils.c | |||
@@ -0,0 +1,141 @@ | |||
1 | /* | ||
2 | * Common modutils related functions for busybox | ||
3 | * | ||
4 | * Copyright (C) 2008 by Timo Teras <timo.teras@iki.fi> | ||
5 | * | ||
6 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | ||
7 | */ | ||
8 | |||
9 | #include "modutils.h" | ||
10 | |||
11 | #ifdef __UCLIBC__ | ||
12 | extern int init_module(void *module, unsigned long len, const char *options); | ||
13 | extern int delete_module(const char *module, unsigned int flags); | ||
14 | #else | ||
15 | # include <sys/syscall.h> | ||
16 | # define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts) | ||
17 | # define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags) | ||
18 | #endif | ||
19 | |||
20 | USE_FEATURE_2_4_MODULES(char *insmod_outputname); | ||
21 | |||
22 | /* | ||
23 | a libbb candidate from ice age! | ||
24 | */ | ||
25 | llist_t FAST_FUNC *llist_find(llist_t *first, const char *str) | ||
26 | { | ||
27 | while (first != NULL) { | ||
28 | if (strcmp(first->data, str) == 0) | ||
29 | return first; | ||
30 | first = first->link; | ||
31 | } | ||
32 | return NULL; | ||
33 | } | ||
34 | |||
35 | void FAST_FUNC replace(char *s, char what, char with) | ||
36 | { | ||
37 | while (*s) { | ||
38 | if (what == *s) | ||
39 | *s = with; | ||
40 | ++s; | ||
41 | } | ||
42 | } | ||
43 | |||
44 | char * FAST_FUNC replace_underscores(char *s) | ||
45 | { | ||
46 | replace(s, '-', '_'); | ||
47 | return s; | ||
48 | } | ||
49 | |||
50 | int FAST_FUNC string_to_llist(char *string, llist_t **llist, const char *delim) | ||
51 | { | ||
52 | char *tok; | ||
53 | int len = 0; | ||
54 | |||
55 | while ((tok = strsep(&string, delim)) != NULL) { | ||
56 | if (tok[0] == '\0') | ||
57 | continue; | ||
58 | llist_add_to_end(llist, xstrdup(tok)); | ||
59 | len += strlen(tok); | ||
60 | } | ||
61 | return len; | ||
62 | } | ||
63 | |||
64 | char * FAST_FUNC filename2modname(const char *filename, char *modname) | ||
65 | { | ||
66 | int i; | ||
67 | char *from; | ||
68 | |||
69 | if (filename == NULL) | ||
70 | return NULL; | ||
71 | if (modname == NULL) | ||
72 | modname = xmalloc(MODULE_NAME_LEN); | ||
73 | from = bb_get_last_path_component_nostrip(filename); | ||
74 | for (i = 0; i < MODULE_NAME_LEN && from[i] != '\0' && from[i] != '.'; i++) | ||
75 | modname[i] = (from[i] == '-') ? '_' : from[i]; | ||
76 | modname[i] = 0; | ||
77 | |||
78 | return modname; | ||
79 | } | ||
80 | |||
81 | const char * FAST_FUNC moderror(int err) | ||
82 | { | ||
83 | switch (err) { | ||
84 | case -1: | ||
85 | return "no such module"; | ||
86 | case ENOEXEC: | ||
87 | return "invalid module format"; | ||
88 | case ENOENT: | ||
89 | return "unknown symbol in module, or unknown parameter"; | ||
90 | case ESRCH: | ||
91 | return "module has wrong symbol version"; | ||
92 | case ENOSYS: | ||
93 | return "kernel does not support requested operation"; | ||
94 | default: | ||
95 | return strerror(err); | ||
96 | } | ||
97 | } | ||
98 | |||
99 | char * FAST_FUNC parse_cmdline_module_options(char **argv) | ||
100 | { | ||
101 | char *options; | ||
102 | int optlen; | ||
103 | |||
104 | options = xzalloc(1); | ||
105 | optlen = 0; | ||
106 | while (*++argv) { | ||
107 | options = xrealloc(options, optlen + 2 + strlen(*argv) + 2); | ||
108 | /* Spaces handled by "" pairs, but no way of escaping quotes */ | ||
109 | optlen += sprintf(options + optlen, (strchr(*argv,' ') ? "\"%s\" " : "%s "), *argv); | ||
110 | } | ||
111 | return options; | ||
112 | } | ||
113 | |||
114 | int FAST_FUNC bb_init_module(const char *filename, const char *options) | ||
115 | { | ||
116 | size_t len = MAXINT(ssize_t); | ||
117 | char *image; | ||
118 | int rc = ENOENT; | ||
119 | |||
120 | #if ENABLE_FEATURE_2_4_MODULES | ||
121 | if (get_linux_version_code() < KERNEL_VERSION(2,6,0)) | ||
122 | return bb_init_module_24(filename, options); | ||
123 | #endif | ||
124 | |||
125 | /* Use the 2.6 way */ | ||
126 | image = (char *) xmalloc_open_zipped_read_close(filename, &len); | ||
127 | if (image) { | ||
128 | if (init_module(image, len, options) != 0) | ||
129 | rc = errno; | ||
130 | else | ||
131 | rc = 0; | ||
132 | free(image); | ||
133 | } | ||
134 | |||
135 | return rc; | ||
136 | } | ||
137 | |||
138 | int FAST_FUNC bb_delete_module(const char *module, unsigned int flags) | ||
139 | { | ||
140 | return delete_module(module, flags); | ||
141 | } | ||