noice

small file browser
git clone git://git.2f30.org/noice
Log | Files | Refs | README | LICENSE

commit 32bce991be84ba1e5ae1cb81bfe48738e4977077
parent 5335be58322644e16f6478539b4f5846a1f80ac8
Author: sin <sin@2f30.org>
Date:   Wed, 22 Oct 2014 16:21:50 +0100

Add dentfill() and dentfree()

Diffstat:
Mnoice.c | 70++++++++++++++++++++++++++++++++++++++++++----------------------------
1 file changed, 42 insertions(+), 28 deletions(-)

diff --git a/noice.c b/noice.c @@ -441,6 +441,46 @@ printent(struct entry *ent, int active) free(name); } +int +dentfill(DIR *dirp, struct entry **dents, + int (*filter)(regex_t *, char *), regex_t *re) +{ + struct dirent *dp; + struct stat sb; + int n = 0; + int r; + + while ((dp = readdir(dirp)) != NULL) { + /* Skip self and parent */ + if (strcmp(dp->d_name, ".") == 0 + || strcmp(dp->d_name, "..") == 0) + continue; + if (filter(re, dp->d_name) == 0) + continue; + *dents = xrealloc(*dents, (n + 1) * sizeof(**dents)); + (*dents)[n].name = xstrdup(dp->d_name); + /* Get mode flags */ + r = fstatat(dirfd(dirp), dp->d_name, &sb, + AT_SYMLINK_NOFOLLOW); + if (r == -1) + printerr(1, "stat"); + (*dents)[n].mode = sb.st_mode; + n++; + } + + return n; +} + +void +dentfree(struct entry *dents, int n) +{ + int i; + + for (i = 0; i < n; i++) + free(dents[i].name); + free(dents); +} + void browse(const char *ipath, const char *ifilter) { @@ -476,31 +516,7 @@ begin: if (r != 0) goto nochange; - while ((dp = readdir(dirp)) != NULL) { - char *name; - - /* Skip self and parent */ - if (strcmp(dp->d_name, ".") == 0 - || strcmp(dp->d_name, "..") == 0) - continue; - if (!visible(&filter_re, dp->d_name)) - continue; - /* Deep copy because readdir(3) reuses the entries */ - dents = xrealloc(dents, (n + 1) * sizeof(*dents)); - dents[n].name = xstrdup(dp->d_name); - /* Handle root case */ - if (strcmp(path, "/") == 0) - asprintf(&name, "/%s", dents[n].name); - else - asprintf(&name, "%s/%s", path, dents[n].name); - /* Get mode flags */ - r = lstat(name, &sb); - free(name); - if (r == -1) - printerr(1, "stat"); - dents[n].mode = sb.st_mode; - n++; - } + n = dentfill(dirp, &dents, visible, &filter_re); /* Make sure cur is in range */ cur = MIN(cur, n - 1); @@ -695,9 +711,7 @@ nochange: } out: - for (i = 0; i < n; i++) - free(dents[i].name); - free(dents); + dentfree(dents, n); /* Should never be null */ r = closedir(dirp);