- use mmap instead of allocating hundreds of megabytes of RAM. +39b
No binary (build failed)
—
(log yok)
| @@ -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; | |
| } | |