diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2015-10-08 17:00:10 +0200 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2015-10-08 17:00:10 +0200 |
commit | 567d60c3af74d0ac4d9d2ed91d0f548963ce9693 (patch) | |
tree | f57ac7623589dc813a575741131b7fc47be4281e /nlplug-findfs.c | |
parent | 4d213b31b890011f120146f0d760d7ffd70f75b9 (diff) | |
download | mkinitfs-567d60c3af74d0ac4d9d2ed91d0f548963ce9693.tar.bz2 mkinitfs-567d60c3af74d0ac4d9d2ed91d0f548963ce9693.tar.xz |
nlplug-findfs: save stackspace while recursing dir tree
avoid allocate PATH_MAX on stack for every dir. Instead reuse the path
buffer.
Diffstat (limited to 'nlplug-findfs.c')
-rw-r--r-- | nlplug-findfs.c | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/nlplug-findfs.c b/nlplug-findfs.c index 9d68cfa..bf2a2ad 100644 --- a/nlplug-findfs.c +++ b/nlplug-findfs.c @@ -264,38 +264,49 @@ struct recurse_opts { void *userdata; }; -void recurse_dir(const char *dir, struct recurse_opts *opts) +/* pathbuf needs hold PATH_MAX chars */ +void recurse_dir(char *pathbuf, struct recurse_opts *opts) { - DIR *d = opendir(dir); + DIR *d = opendir(pathbuf); struct dirent *entry; if (d == NULL) return; while ((entry = readdir(d)) != NULL) { - char path[PATH_MAX]; struct stat st; + size_t pathlen = strlen(pathbuf); + size_t namelen = strlen(entry->d_name); /* d_type is not supported by all filesystems so we need lstat */ - snprintf(path, sizeof(path), "%s/%s", dir, entry->d_name); - if (lstat(path, &st) < 0) { - dbg("%s: %s", path, strerror(errno)); + if (pathlen + 2 + namelen > PATH_MAX) { + dbg("path length overflow"); continue; } + pathbuf[pathlen] = '/'; + strcpy(&pathbuf[pathlen+1], entry->d_name); + + if (lstat(pathbuf, &st) < 0) { + dbg("%s: %s", pathbuf, strerror(errno)); + goto next; + } + if (S_ISDIR(st.st_mode)) { if (entry->d_name[0] == '.') - continue; + goto next; } else if (opts->searchname && strcmp(entry->d_name, opts->searchname) != 0) { - continue; + goto next; } if (S_ISDIR(st.st_mode)) - recurse_dir(path, opts); + recurse_dir(pathbuf, opts); else - opts->callback(path, opts->userdata); + opts->callback(pathbuf, opts->userdata); +next: + pathbuf[pathlen] = '\0'; } closedir(d); } @@ -570,8 +581,11 @@ void *trigger_thread(void *data) .callback = trigger_uevent_cb, .userdata = NULL, }; - recurse_dir("/sys/bus", &opts); - recurse_dir("/sys/devices", &opts); + char path[PATH_MAX] = "/sys/bus"; + + recurse_dir(path, &opts); + strcpy(path, "/sys/devices"); + recurse_dir(path, &opts); write(fd, &ok, sizeof(ok)); return NULL; } |