aboutsummaryrefslogtreecommitdiffstats
path: root/noice.c
diff options
context:
space:
mode:
authorsin <sin@2f30.org>2014-10-22 16:21:50 +0100
committersin <sin@2f30.org>2014-10-22 16:22:05 +0100
commit32bce991be84ba1e5ae1cb81bfe48738e4977077 (patch)
tree741a879d56e266dd043249b8315f6e6669b52c75 /noice.c
parent5335be58322644e16f6478539b4f5846a1f80ac8 (diff)
downloadnoice-32bce991be84ba1e5ae1cb81bfe48738e4977077.tar.gz
Add dentfill() and dentfree()
Diffstat (limited to 'noice.c')
-rw-r--r--noice.c70
1 files changed, 42 insertions, 28 deletions
diff --git a/noice.c b/noice.c
index f983fef..42a1d0d 100644
--- 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);
Un proyecto texto-plano.xyz