diff options
author | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2008-05-26 15:12:01 +0000 |
---|---|---|
committer | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2008-05-26 15:12:01 +0000 |
commit | cf18010ca966aa2be06e0466aeb78b54d15957e2 (patch) | |
tree | 3df37379ce244c74b54c04398f31f630e334409e /modutils | |
parent | dc5d7fec350532d191ecfef49fa8b9b208b09f9f (diff) | |
download | busybox-w32-cf18010ca966aa2be06e0466aeb78b54d15957e2.tar.gz busybox-w32-cf18010ca966aa2be06e0466aeb78b54d15957e2.tar.bz2 busybox-w32-cf18010ca966aa2be06e0466aeb78b54d15957e2.zip |
- use mmap instead of allocating hundreds of megabytes of RAM. +39b
Diffstat (limited to 'modutils')
-rw-r--r-- | modutils/depmod.c | 63 |
1 files changed, 43 insertions, 20 deletions
diff --git a/modutils/depmod.c b/modutils/depmod.c index 489a0330e..5d51ba450 100644 --- a/modutils/depmod.c +++ b/modutils/depmod.c | |||
@@ -11,6 +11,12 @@ | |||
11 | #include <libbb.h> | 11 | #include <libbb.h> |
12 | #include <sys/utsname.h> /* uname() */ | 12 | #include <sys/utsname.h> /* uname() */ |
13 | 13 | ||
14 | /* | ||
15 | * Theory of operation: | ||
16 | * - iterate over all modules and record their full path | ||
17 | * - iterate over all modules looking for "depends=" entries | ||
18 | * for each depends, look through our list of full paths and emit if found | ||
19 | */ | ||
14 | struct globals { | 20 | struct globals { |
15 | llist_t *lst; | 21 | llist_t *lst; |
16 | }; | 22 | }; |
@@ -25,40 +31,56 @@ static int fill_lst(const char *modulename, struct stat ATTRIBUTE_UNUSED *sb, | |||
25 | return TRUE; | 31 | return TRUE; |
26 | } | 32 | } |
27 | 33 | ||
28 | static int fileAction(const char *fname, struct stat ATTRIBUTE_UNUSED *sb, | 34 | static int fileAction(const char *fname, struct stat *sb, |
29 | void *data, int ATTRIBUTE_UNUSED depth) | 35 | void *data, int ATTRIBUTE_UNUSED depth) |
30 | { | 36 | { |
31 | size_t seen = 0; | 37 | size_t len = sb->st_size; |
32 | size_t len = MAXINT(ssize_t); | 38 | void *the_module, *ptr; |
33 | void *the_module = xmalloc_open_read_close(fname, &len), *ptr = the_module; | 39 | int fd; |
34 | const char *deps; | 40 | char *depends, *deps; |
35 | RESERVE_CONFIG_BUFFER(depends, 512); | ||
36 | RESERVE_CONFIG_BUFFER(buf1, 512); | ||
37 | |||
38 | memset(depends, 0, sizeof(depends)); | ||
39 | 41 | ||
42 | /*XXX: FIXME: does not handle compressed modules! | ||
43 | * There should be a function that looks at the extension and sets up | ||
44 | * open_transformer for us. | ||
45 | */ | ||
40 | if (last_char_is(fname, 'o') == NULL) /* not a module */ | 46 | if (last_char_is(fname, 'o') == NULL) /* not a module */ |
41 | goto done; | 47 | goto skip; |
48 | |||
49 | fd = xopen(fname, O_RDONLY); | ||
50 | the_module = mmap(NULL, len, PROT_READ, MAP_SHARED | ||
51 | #if defined MAP_POPULATE | ||
52 | |MAP_POPULATE | ||
53 | #endif | ||
54 | , fd, 0); | ||
55 | close(fd); | ||
56 | if (the_module == MAP_FAILED) | ||
57 | bb_perror_msg_and_die("mmap"); | ||
58 | |||
59 | ptr = the_module; | ||
60 | |||
42 | fprintf((FILE*)data, "\n%s:", fname); | 61 | fprintf((FILE*)data, "\n%s:", fname); |
43 | //bb_info_msg("[%d] fname='%s'", (int)data, fname); | 62 | //bb_info_msg("fname='%s'", fname); |
44 | do { | 63 | do { |
45 | /* search for a 'd' */ | 64 | /* search for a 'd' */ |
46 | ptr = memchr(ptr, 'd', len - seen); | 65 | ptr = memchr(ptr, 'd', len); |
47 | if (ptr == NULL) /* no d left, done */ | 66 | if (ptr == NULL) /* no d left, done */ |
67 | goto done; | ||
68 | if (memcmp(ptr, "depends=", sizeof("depends=")-1) == 0) | ||
48 | break; | 69 | break; |
49 | if (sscanf(ptr, "depends=%s", depends) == 1) | 70 | len -= ++ptr - the_module; |
50 | break; | ||
51 | seen = ++ptr - the_module; | ||
52 | } while (1); | 71 | } while (1); |
72 | deps = depends = strdup (ptr + sizeof("depends=")-1); | ||
53 | //bb_info_msg(" depends='%s'", depends); | 73 | //bb_info_msg(" depends='%s'", depends); |
54 | deps = depends; | ||
55 | while (*deps) { | 74 | while (*deps) { |
56 | llist_t * _lst = G.lst; | 75 | llist_t * _lst = G.lst; |
76 | char *buf1; | ||
77 | |||
57 | ptr = strchr(deps, ','); | 78 | ptr = strchr(deps, ','); |
58 | if (ptr != NULL) | 79 | if (ptr != NULL) |
59 | *(char*)ptr = '\0'; | 80 | *(char*)ptr = '\0'; |
60 | /* remember the length of the current dependency plus eventual 0 byte */ | 81 | /* remember the length of the current dependency plus eventual 0 byte */ |
61 | len = strlen(deps) + (ptr != NULL); | 82 | len = strlen(deps) + (ptr != NULL); |
83 | buf1 = xmalloc(len + 3); | ||
62 | sprintf(buf1, "/%s.", deps); /* make sure we match the correct file */ | 84 | sprintf(buf1, "/%s.", deps); /* make sure we match the correct file */ |
63 | while (_lst) { | 85 | while (_lst) { |
64 | ptr = strstr(_lst->data, buf1); | 86 | ptr = strstr(_lst->data, buf1); |
@@ -66,16 +88,17 @@ static int fileAction(const char *fname, struct stat ATTRIBUTE_UNUSED *sb, | |||
66 | break; /* found it */ | 88 | break; /* found it */ |
67 | _lst = _lst->link; | 89 | _lst = _lst->link; |
68 | } | 90 | } |
69 | if (_lst && _lst->data) { | 91 | free(buf1); |
92 | if (_lst /*&& _lst->data*/) { | ||
70 | //bb_info_msg("[%s] -> '%s'", deps, _lst->data); | 93 | //bb_info_msg("[%s] -> '%s'", deps, _lst->data); |
71 | fprintf((FILE*)data, " %s", _lst->data); | 94 | fprintf((FILE*)data, " %s", _lst->data); |
72 | deps += len; | 95 | deps += len; |
73 | } | 96 | } |
74 | } | 97 | } |
98 | free(depends); | ||
75 | done: | 99 | done: |
76 | RELEASE_CONFIG_BUFFER(depends); | 100 | munmap(the_module, sb->st_size); |
77 | RELEASE_CONFIG_BUFFER(buf1); | 101 | skip: |
78 | free(the_module); | ||
79 | return TRUE; | 102 | return TRUE; |
80 | } | 103 | } |
81 | 104 | ||