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 | |
parent | dc5d7fec350532d191ecfef49fa8b9b208b09f9f (diff) | |
download | busybox-cf18010ca966aa2be06e0466aeb78b54d15957e2.tar.gz |
- use mmap instead of allocating hundreds of megabytes of RAM. +39b
-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 @@ #include <libbb.h> #include <sys/utsname.h> /* uname() */ +/* + * Theory of operation: + * - iterate over all modules and record their full path + * - iterate over all modules looking for "depends=" entries + * for each depends, look through our list of full paths and emit if found + */ struct globals { llist_t *lst; }; @@ -25,40 +31,56 @@ static int fill_lst(const char *modulename, struct stat ATTRIBUTE_UNUSED *sb, return TRUE; } -static int fileAction(const char *fname, struct stat ATTRIBUTE_UNUSED *sb, +static int fileAction(const char *fname, struct stat *sb, void *data, int ATTRIBUTE_UNUSED depth) { - size_t seen = 0; - size_t len = MAXINT(ssize_t); - void *the_module = xmalloc_open_read_close(fname, &len), *ptr = the_module; - const char *deps; - RESERVE_CONFIG_BUFFER(depends, 512); - RESERVE_CONFIG_BUFFER(buf1, 512); - - memset(depends, 0, sizeof(depends)); + size_t len = sb->st_size; + void *the_module, *ptr; + int fd; + char *depends, *deps; +/*XXX: FIXME: does not handle compressed modules! + * There should be a function that looks at the extension and sets up + * open_transformer for us. + */ if (last_char_is(fname, 'o') == NULL) /* not a module */ - goto done; + goto skip; + + fd = xopen(fname, O_RDONLY); + the_module = mmap(NULL, len, PROT_READ, MAP_SHARED +#if defined MAP_POPULATE + |MAP_POPULATE +#endif + , fd, 0); + close(fd); + if (the_module == MAP_FAILED) + bb_perror_msg_and_die("mmap"); + + ptr = the_module; + fprintf((FILE*)data, "\n%s:", fname); -//bb_info_msg("[%d] fname='%s'", (int)data, fname); +//bb_info_msg("fname='%s'", fname); do { /* search for a 'd' */ - ptr = memchr(ptr, 'd', len - seen); + ptr = memchr(ptr, 'd', len); if (ptr == NULL) /* no d left, done */ + goto done; + if (memcmp(ptr, "depends=", sizeof("depends=")-1) == 0) break; - if (sscanf(ptr, "depends=%s", depends) == 1) - break; - seen = ++ptr - the_module; + len -= ++ptr - the_module; } while (1); + deps = depends = strdup (ptr + sizeof("depends=")-1); //bb_info_msg(" depends='%s'", depends); - deps = depends; while (*deps) { llist_t * _lst = G.lst; + char *buf1; + ptr = strchr(deps, ','); if (ptr != NULL) *(char*)ptr = '\0'; /* remember the length of the current dependency plus eventual 0 byte */ len = strlen(deps) + (ptr != NULL); + buf1 = xmalloc(len + 3); sprintf(buf1, "/%s.", deps); /* make sure we match the correct file */ while (_lst) { ptr = strstr(_lst->data, buf1); @@ -66,16 +88,17 @@ static int fileAction(const char *fname, struct stat ATTRIBUTE_UNUSED *sb, break; /* found it */ _lst = _lst->link; } - if (_lst && _lst->data) { + free(buf1); + if (_lst /*&& _lst->data*/) { //bb_info_msg("[%s] -> '%s'", deps, _lst->data); fprintf((FILE*)data, " %s", _lst->data); deps += len; } } + free(depends); done: - RELEASE_CONFIG_BUFFER(depends); - RELEASE_CONFIG_BUFFER(buf1); - free(the_module); + munmap(the_module, sb->st_size); +skip: return TRUE; } |